2 * $Source: /cvs/cvsroot/d2x/arch/win32/ipx_win.c,v $
5 * $Date: 2001-10-19 10:52:38 $
7 * IPX driver using BSD style sockets
8 * Mostly taken from dosemu
10 * $Log: not supported by cvs2svn $
11 * Revision 1.2 2001/10/19 00:23:56 bradleyb
12 * Moved win32_* to win32/ (a la d1x), starting to get net working.
14 * Revision 1.3 2001/01/29 13:35:09 bradleyb
15 * Fixed build system, minor fixes
33 static ipx_socket_t mysock;
35 //#define n_printf(format, args...) mprintf((1, format, ## args))
37 static int ipx_win_GetMyAddress( void )
41 struct sockaddr_ipx ipxs;
42 struct sockaddr_ipx ipxs2;
46 // sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
47 sock=socket(AF_IPX,SOCK_DGRAM,0);
51 mprintf((1,"IPX: could not open socket in GetMyAddress\n"));
55 /* bind this socket to network 0 */
56 ipxs.sa_family=AF_IPX;
57 #ifdef IPX_MANUAL_ADDRESS
58 memcpy(ipxs.sa_netnum, ipx_MyAddress, 4);
60 memset(ipxs.sa_netnum, 0, 4);
64 if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1)
66 mprintf((1,"IPX: could bind to network 0 in GetMyAddress\n"));
72 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
73 mprintf((1,"IPX: could not get socket name in GetMyAddress\n"));
78 memcpy(ipx_MyAddress, ipxs2.sa_netnum, 4);
79 for (i = 0; i < 6; i++) {
80 ipx_MyAddress[4+i] = ipxs2.sa_nodenum[i];
82 /* printf("My address is 0x%.4X:%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\n", *((int *)ipxs2.sa_netnum), ipxs2.sa_nodenum[0],
83 ipxs2.sa_nodenum[1], ipxs2.sa_nodenum[2], ipxs2.sa_nodenum[3], ipxs2.sa_nodenum[4], ipxs2.sa_nodenum[5]);*/
91 static int ipx_win_OpenSocket(int port)
93 int sock; /* sock here means Linux socket handle */
95 struct sockaddr_ipx ipxs;
97 struct sockaddr_ipx ipxs2;
99 WORD wVersionRequested;
102 wVersionRequested = MAKEWORD(2, 0);
103 if (WSAStartup( wVersionRequested, &wsaData))
108 if ( LOBYTE( wsaData.wVersion ) != 2 ||
109 HIBYTE( wsaData.wVersion ) != 0 ) {
110 /* We couldn't find a usable WinSock DLL. */
117 /* DANG_FIXTHIS - kludge to support broken linux IPX stack */
118 /* need to convert dynamic socket open into a real socket number */
120 mprintf((1,"IPX: using socket %x\n", nextDynamicSocket));
121 port = nextDynamicSocket++;
124 /* do a socket call, then bind to this port */
125 // sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
126 // sock = socket(AF_IPX, SOCK_DGRAM, 0);
127 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)
129 mprintf((1,"IPX: could not open IPX socket.\n"));
135 /* Permit broadcast output */
136 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
137 (const char *)&opt, sizeof(opt)) == -1) {
138 mprintf((1,"IPX: could not set socket option for broadcast.\n"));
141 ipxs.sa_family = AF_IPX;
142 memcpy(ipxs.sa_netnum, ipx_MyAddress, 4);
143 // *((unsigned int *)&ipxs.sa_netnum[0]) = *((unsigned int *)&ipx_MyAddress[0]);
144 /* ipxs.sa_netnum = htonl(MyNetwork); */
145 memset(ipxs.sa_nodenum, 0, 6);
146 // bzero(ipxs.sa_nodenum, 6); /* Please fill in my node name */
147 ipxs.sa_socket = htons((short)port);
149 /* now bind to this port */
150 if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) {
151 mprintf((1,"IPX: could not bind socket to address\n"));
157 // len = sizeof(ipxs2);
158 // if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
159 // //n_printf("IPX: could not get socket name in IPXOpenSocket\n");
160 // closesocket( sock );
163 // port = htons(ipxs2.sa_socket);
164 // //n_printf("IPX: opened dynamic socket %04x\n", port);
167 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
168 mprintf((1,"IPX: could not get socket name in IPXOpenSocket\n"));
173 port = htons(ipxs2.sa_socket);
174 mprintf((1,"IPX: opened dynamic socket %04x\n", port));
177 memcpy(ipx_MyAddress, ipxs2.sa_netnum, 4);
178 memcpy(ipx_MyAddress + 4, ipxs2.sa_nodenum, 6);
181 mysock.socket = port;
183 ipx_win_GetMyAddress();
188 static void ipx_win_CloseSocket(void) {
189 /* now close the file descriptor for the socket, and free it */
190 mprintf((1,"IPX: closing file descriptor on socket %x\n", mysock.socket));
191 closesocket(mysock.fd);
195 static int ipx_win_SendPacket(IPXPacket_t *IPXHeader,
196 ubyte *data, int dataLen) {
197 struct sockaddr_ipx ipxs;
199 ipxs.sa_family = AF_IPX;
200 /* get destination address from IPX packet header */
201 memcpy(&ipxs.sa_netnum, IPXHeader->Destination.Network, 4);
202 /* if destination address is 0, then send to my net */
203 if ((*(unsigned int *)&ipxs.sa_netnum) == 0) {
204 (*(unsigned int *)&ipxs.sa_netnum)= *((unsigned int *)&ipx_MyAddress[0]);
205 /* ipxs.sa_netnum = htonl(MyNetwork); */
207 memcpy(&ipxs.sa_nodenum, IPXHeader->Destination.Node, 6);
208 // memcpy(&ipxs.sa_socket, IPXHeader->Destination.Socket, 2);
209 ipxs.sa_socket=htons(mysock.socket);
210 // ipxs.sa_type = IPXHeader->PacketType;
211 /* ipxs.sipx_port=htons(0x452); */
212 return sendto(mysock.fd, data, dataLen, 0,
213 (struct sockaddr *) &ipxs, sizeof(ipxs));
216 static int ipx_win_ReceivePacket(char *buffer, int bufsize,
217 struct ipx_recv_data *rd) {
219 struct sockaddr_ipx ipxs;
222 if ((size = recvfrom(mysock.fd, buffer, bufsize, 0,
223 (struct sockaddr *) &ipxs, &sz)) <= 0)
225 memcpy(rd->src_network, ipxs.sa_netnum, 4);
226 memcpy(rd->src_node, ipxs.sa_nodenum, 6);
227 rd->src_socket = ipxs.sa_socket;
228 rd->dst_socket = mysock.socket;
229 // rd->pkt_type = ipxs.sipx_type;
234 static int ipx_win_general_PacketReady(void) {
235 return ipx_general_PacketReady(mysock.fd);
238 struct ipx_driver ipx_win = {
239 // ipx_win_GetMyAddress,
243 ipx_win_ReceivePacket,
244 ipx_win_general_PacketReady,