]> icculus.org git repositories - btb/d2x.git/blob - arch/linux/ukali.c
networking works, finally
[btb/d2x.git] / arch / linux / ukali.c
1 /*
2  * $Source: /cvs/cvsroot/d2x/arch/linux/ukali.c,v $
3  * $Revision: 1.3 $
4  * $Author: bradleyb $
5  * $Date: 2001-10-19 07:39:26 $
6  *
7  * FIXME: add description
8  *
9  * $Log: not supported by cvs2svn $
10  * Revision 1.2  2001/10/19 07:29:37  bradleyb
11  * Brought linux networking in line with d1x, moved some arch/linux_* stuff to arch/linux/
12  *
13  *
14  */
15
16 #ifdef HAVE_CONFIG_H
17 #include <conf.h>
18 #endif
19
20 #include <sys/socket.h>
21 #include <sys/types.h>
22 #include <string.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <netdb.h>
26 #include <stdlib.h>
27 #include <sys/time.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include "ukali.h"
32 //added 05/17/99 Matt Mueller - needed to redefine FD_* so that no asm is used
33 #include "checker.h"
34 //end addition -MM
35 int g_sockfd = -1;
36 struct sockaddr_in kalinix_addr;
37 char g_mynodenum[6];
38
39 int knix_newSock(void) {
40
41         int tempsock;
42         struct sockaddr_in taddr;
43
44         taddr.sin_family = AF_INET;
45         taddr.sin_addr.s_addr = inet_addr("127.0.0.1");
46         taddr.sin_port = 0;
47
48         if ((tempsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
49                 return -1;
50
51         fcntl(tempsock, F_SETFL, fcntl(tempsock, F_GETFL) | O_NONBLOCK);
52
53         if ((bind(tempsock, (struct sockaddr *)&taddr, sizeof(taddr))) < 0) {
54                 close(tempsock);
55                 return -1;
56         }
57         return tempsock;
58 }
59
60 int knix_Send(int hand, char *data, int len) {
61         int i = 0, t;
62
63         while ((t = sendto(hand, data, len, 0, (struct sockaddr *)&kalinix_addr, 
64                         sizeof(kalinix_addr))) < 0) {
65                 i++;
66                 if (i > 10)
67                         return 0;
68         }
69
70         return t;
71 }
72
73 int knix_Recv(int hand, char *data, int len) {
74         struct sockaddr_in taddr;
75         int tlen;
76
77         tlen = sizeof(taddr);
78
79         return recvfrom(hand, data, len, 0, (struct sockaddr *)&taddr, &tlen);
80
81 }
82
83 int knix_WaitforSocket(int hand, int timems) {
84         fd_set set;
85         struct timeval tv;
86
87         FD_ZERO(&set);
88         FD_SET(hand, &set);
89         tv.tv_sec = 0;
90         // 100ms
91         tv.tv_usec = timems * 1000;
92         return select(hand + 1, &set, NULL, NULL, &tv);
93 }
94
95 int knix_ReceivePacket(int hand, char *outdata, int *outlen, kaliaddr_ipx *from) {
96         static char data[MAX_PACKET_SIZE];
97         int len;
98
99         len = knix_Recv(hand, data, sizeof(data));
100
101         if (len <= 0) return 0;
102
103         switch (data[0]) {
104 //              case 1: // open socket
105 //                      break;
106 //              case 2: // close socket
107 //                      break;
108                 case 3: // received data packet
109                         if (len < 11) break;
110                         if (!outdata)
111                                 break;
112                         from->sa_family = AF_IPX;
113                         memcpy(from->sa_nodenum, &data[1], sizeof(from->sa_nodenum));
114                         memset(from->sa_netnum, 0, sizeof(from->sa_netnum));
115                         memcpy(&from->sa_socket, &data[9], sizeof(unsigned short));
116                         memcpy(outdata, &data[11], len-11 > *outlen ? *outlen : len-11);
117                         *outlen = len-11;
118                         break;
119                 case 4: // myipxaddress
120                         if (len < 7) break;
121                         memcpy(g_mynodenum, &data[1], 6);
122                         break;
123 //              case 5: // Init KaliNix connection
124 //                      break;
125                 case 6: // open response
126                 case 7: // close response
127                         if (len < 3) break;
128 //                      memcpy(g_LastPort, &data[1], sizeof(g_LastPort))
129                         break;
130         }
131
132         return data[0];
133
134 }
135
136 int knix_GetMyAddress(void) {
137         char initdata[1];
138
139         if (g_sockfd < 0) {
140                 kalinix_addr.sin_family = AF_INET;
141                 kalinix_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
142                 kalinix_addr.sin_port = htons(4213);
143
144                 g_sockfd = knix_newSock();
145         }
146
147         initdata[0] = 5; // Get Address
148         knix_Send(g_sockfd, initdata, sizeof(initdata));
149
150         return 0;
151
152 }
153
154 int KaliSendPacket(int hand, char *data, int len, kaliaddr_ipx *to) {
155         static char sendbuf[MAX_PACKET_SIZE+11];
156 //              char    code; == 3
157 //              char    sa_nodenum[6];
158 //              char    dport[2];
159 //              char    sport[2];
160 //              char data[];
161
162         sendbuf[0] = 3;
163         memcpy(&sendbuf[1], to->sa_nodenum, sizeof(to->sa_nodenum));
164         memcpy(&sendbuf[7], &to->sa_socket, sizeof(to->sa_socket));
165         memset(&sendbuf[9], 0, sizeof(to->sa_socket));
166         len = len > MAX_PACKET_SIZE ? MAX_PACKET_SIZE : len;
167         memcpy(&sendbuf[11], data, len);
168
169         if (!knix_Send(hand, sendbuf, len+11)){
170                 return -1;
171         }
172         return len;
173
174 }
175
176 int KaliReceivePacket(int hand, char *data, int len, kaliaddr_ipx *from) {
177         int newlen;
178         int t;
179
180         newlen = len;
181
182         t = knix_ReceivePacket(hand, data, &newlen, from);
183
184         while (t != 0 && t != 3)
185                 t = knix_ReceivePacket(hand, data, &newlen, from);
186
187         if (t == 3)
188                 return newlen;
189         else return -1;
190
191 }
192
193 int KaliGetNodeNum(kaliaddr_ipx *myaddr) {
194         int tcount = 0;
195
196         if (g_sockfd < 0 && knix_GetMyAddress())
197                 return -1;
198
199         while (tcount < 5) {
200                 if (knix_WaitforSocket(g_sockfd, 100) > 0) {
201                         if (knix_ReceivePacket(g_sockfd, NULL, 0, NULL) == 4)
202                                 break;
203                         continue;
204                 }
205                 knix_GetMyAddress();
206                 tcount++;
207         }
208         if (tcount == 5)
209                 return -1;
210
211         close(g_sockfd);
212         g_sockfd = -1;
213         memcpy(myaddr->sa_nodenum, g_mynodenum, sizeof(g_mynodenum));
214
215         return 0;
216
217 }
218
219 int KaliCloseSocket(int hand) {
220         char opendata[3] = {2, 0, 0};
221         int tcount = 0;
222
223         knix_Send(hand, opendata, sizeof(opendata));
224
225         while (tcount < 5) {
226
227                 if (knix_WaitforSocket(hand, 100) > 0) {
228                         if (knix_ReceivePacket(hand, NULL, 0, NULL) == 7)
229                                 break;
230                         continue;
231                 }
232                 knix_Send(hand, opendata, sizeof(opendata));
233                 tcount++;
234         }
235         close(hand);
236         return 0;
237
238 }
239
240 int KaliOpenSocket(unsigned short port) {
241         char opendata[16];
242         int hand;
243         int tcount = 0;
244         long pid;
245
246         opendata[0] = 1; // open socket
247         memcpy(&opendata[1], &port, sizeof(port));
248         pid = (int)htonl(getpid());
249         memcpy(&opendata[3], &pid, sizeof(pid));
250         strncpy(&opendata[7], KALI_PROCESS_NAME, sizeof(KALI_PROCESS_NAME));
251         opendata[15] = 0;
252
253         if ((hand = knix_newSock()) < 0)
254                 return -1;
255
256         knix_Send(hand, opendata, sizeof(opendata));
257
258         while (tcount < 5) {
259
260                 if (knix_WaitforSocket(hand, 100) > 0) {
261                         if (knix_ReceivePacket(hand, NULL, 0, NULL) == 6)
262                                 break;
263                         continue;
264                 }
265                 knix_Send(hand, opendata, sizeof(opendata));
266                 tcount++;
267         }
268
269         if (tcount == 5) {
270                 close(hand);
271                 return -1;
272         }
273
274         return hand;
275 }
276