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