win32 networking backtrack
[btb/d2x.git] / arch / win32 / ipx_win.c
1 /* $Id: ipx_win.c,v 1.4 2002-08-31 03:16:35 btb Exp $ */
2
3 /*
4  *
5  * IPX driver using BSD style sockets
6  * Mostly taken from dosemu
7  *
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <conf.h>
12 #endif
13
14 #include <string.h>
15 #include <stdlib.h>
16 #include <winsock.h>
17 #include <wsipx.h>
18 #include <errno.h>
19
20 #include "ipx_drv.h"
21
22 #include "mono.h"
23
24 //#define n_printf(format, args...) mprintf((1, format, ## args))
25
26 static int ipx_win_GetMyAddress( void )
27 {
28 #if 0
29   int sock;
30   struct sockaddr_ipx ipxs;
31   struct sockaddr_ipx ipxs2;
32   int len;
33   int i;
34   
35 //  sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
36   sock=socket(AF_IPX,SOCK_DGRAM,0);
37
38   if(sock==-1)
39   {
40     mprintf((1,"IPX: could not open socket in GetMyAddress\n"));
41     return(-1);
42   }
43
44   /* bind this socket to network 0 */  
45   ipxs.sa_family=AF_IPX;
46 #ifdef IPX_MANUAL_ADDRESS
47   memcpy(ipxs.sa_netnum, ipx_MyAddress, 4);
48 #else
49   memset(ipxs.sa_netnum, 0, 4);
50 #endif  
51   ipxs.sa_socket=0;
52   
53   if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1)
54   {
55     mprintf((1,"IPX: could bind to network 0 in GetMyAddress\n"));
56     closesocket( sock );
57     return(-1);
58   }
59   
60   len = sizeof(ipxs2);
61   if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
62     mprintf((1,"IPX: could not get socket name in GetMyAddress\n"));
63     closesocket( sock );
64     return(-1);
65   }
66
67   memcpy(ipx_MyAddress, ipxs2.sa_netnum, 4);
68   for (i = 0; i < 6; i++) {
69     ipx_MyAddress[4+i] = ipxs2.sa_nodenum[i];
70   }
71 /*  printf("My address is 0x%.4X:%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\n", *((int *)ipxs2.sa_netnum), ipxs2.sa_nodenum[0],
72   ipxs2.sa_nodenum[1], ipxs2.sa_nodenum[2], ipxs2.sa_nodenum[3], ipxs2.sa_nodenum[4], ipxs2.sa_nodenum[5]);*/
73
74     closesocket( sock );
75
76 #endif
77   return(0);
78 }
79
80 static int ipx_win_OpenSocket(ipx_socket_t *sk, int port)
81 {
82   int sock;                     /* sock here means Linux socket handle */
83   int opt;
84   struct sockaddr_ipx ipxs;
85   int len;
86   struct sockaddr_ipx ipxs2;
87
88   /* DANG_FIXTHIS - kludge to support broken linux IPX stack */
89   /* need to convert dynamic socket open into a real socket number */
90 /*  if (port == 0) {
91     mprintf((1,"IPX: using socket %x\n", nextDynamicSocket));
92     port = nextDynamicSocket++;
93   }
94 */
95   /* do a socket call, then bind to this port */
96 //  sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
97   sock = socket(AF_IPX, SOCK_DGRAM, 0);
98   if (sock == -1) {
99     mprintf((1,"IPX: could not open IPX socket.\n"));
100     return -1;
101   }
102
103
104   opt = 1;
105   /* Permit broadcast output */
106   if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
107                  (const char *)&opt, sizeof(opt)) == -1) {
108     mprintf((1,"IPX: could not set socket option for broadcast.\n"));
109     return -1;
110   }
111   ipxs.sa_family = AF_IPX;
112   memcpy(ipxs.sa_netnum, ipx_MyAddress, 4);
113 //  *((unsigned int *)&ipxs.sa_netnum[0]) = *((unsigned int *)&ipx_MyAddress[0]);
114 /*  ipxs.sa_netnum = htonl(MyNetwork); */
115   memset(ipxs.sa_nodenum, 0, 6);
116 //  bzero(ipxs.sa_nodenum, 6);  /* Please fill in my node name */
117   ipxs.sa_socket = htons((short)port);
118
119   /* now bind to this port */
120   if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) {
121     mprintf((1,"IPX: could not bind socket to address\n"));
122     closesocket( sock );
123     return -1;
124   }
125   
126 //  if( port==0 ) {
127 //    len = sizeof(ipxs2);
128 //    if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
129 //       //n_printf("IPX: could not get socket name in IPXOpenSocket\n");
130 //     closesocket( sock );
131 //      return -1;
132 //    } else {
133 //      port = htons(ipxs2.sa_socket);
134 //      //n_printf("IPX: opened dynamic socket %04x\n", port);
135 //    }
136   len = sizeof(ipxs2);
137   if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
138     mprintf((1,"IPX: could not get socket name in IPXOpenSocket\n"));
139     closesocket( sock );
140     return -1;
141   } 
142   if (port == 0) {
143     port = htons(ipxs2.sa_socket);
144     mprintf((1,"IPX: opened dynamic socket %04x\n", port));
145   }
146
147   memcpy(ipx_MyAddress, ipxs2.sa_netnum, 4);
148   memcpy(ipx_MyAddress + 4, ipxs2.sa_nodenum, 6);
149
150   sk->fd = sock;
151   sk->socket = port;
152   return 0;
153 }
154
155 static void ipx_win_CloseSocket(ipx_socket_t *mysock) {
156   /* now close the file descriptor for the socket, and free it */
157   mprintf((1,"IPX: closing file descriptor on socket %x\n", mysock->socket));
158   closesocket(mysock->fd);
159 }
160
161 static int ipx_win_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader,
162  u_char *data, int dataLen) {
163   struct sockaddr_ipx ipxs;
164  
165   ipxs.sa_family = AF_IPX;
166   /* get destination address from IPX packet header */
167   memcpy(&ipxs.sa_netnum, IPXHeader->Destination.Network, 4);
168   /* if destination address is 0, then send to my net */
169   if ((*(unsigned int *)&ipxs.sa_netnum) == 0) {
170     (*(unsigned int *)&ipxs.sa_netnum)= *((unsigned int *)&ipx_MyAddress[0]);
171 /*  ipxs.sa_netnum = htonl(MyNetwork); */
172   }
173   memcpy(&ipxs.sa_nodenum, IPXHeader->Destination.Node, 6);
174   memcpy(&ipxs.sa_socket, IPXHeader->Destination.Socket, 2);
175 //  ipxs.sa_type = IPXHeader->PacketType;
176   /*    ipxs.sipx_port=htons(0x452); */
177   return sendto(mysock->fd, data, dataLen, 0,
178              (struct sockaddr *) &ipxs, sizeof(ipxs));
179 }
180
181 static int ipx_win_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize, 
182  struct ipx_recv_data *rd) {
183         int sz, size;
184         struct sockaddr_ipx ipxs;
185  
186         sz = sizeof(ipxs);
187         if ((size = recvfrom(s->fd, buffer, bufsize, 0,
188              (struct sockaddr *) &ipxs, &sz)) <= 0)
189              return size;
190         memcpy(rd->src_network, ipxs.sa_netnum, 4);
191         memcpy(rd->src_node, ipxs.sa_nodenum, 6);
192         rd->src_socket = ipxs.sa_socket;
193         rd->dst_socket = s->socket;
194 //      rd->pkt_type = ipxs.sipx_type;
195   
196         return size;
197 }
198
199 struct ipx_driver ipx_win = {
200         ipx_win_GetMyAddress,
201         ipx_win_OpenSocket,
202         ipx_win_CloseSocket,
203         ipx_win_SendPacket,
204         ipx_win_ReceivePacket,
205         ipx_general_PacketReady
206 };