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