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