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