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