4 * IPX driver using BSD style sockets
5 * Mostly taken from dosemu
23 #define _do_mprintf(n, format, args...) printf(format, ## args)
24 #define mprintf(args) _do_mprintf args
29 //#define n_printf(format, args...) mprintf((1, format, ## args))
31 static int ipx_win_GetMyAddress( void )
35 struct sockaddr_ipx ipxs;
36 struct sockaddr_ipx ipxs2;
40 // sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
41 sock=socket(AF_IPX,SOCK_DGRAM,0);
45 mprintf((1,"IPX: could not open socket in GetMyAddress\n"));
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);
54 memset(ipxs.sa_netnum, 0, 4);
58 if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1)
60 mprintf((1,"IPX: could bind to network 0 in GetMyAddress\n"));
66 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
67 mprintf((1,"IPX: could not get socket name in GetMyAddress\n"));
72 memcpy(ipx_MyAddress, ipxs2.sa_netnum, 4);
73 for (i = 0; i < 6; i++) {
74 ipx_MyAddress[4+i] = ipxs2.sa_nodenum[i];
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]);*/
85 static int ipx_win_OpenSocket(ipx_socket_t *sk, int port)
87 int sock; /* sock here means Linux socket handle */
89 struct sockaddr_ipx ipxs;
91 struct sockaddr_ipx ipxs2;
93 /* DANG_FIXTHIS - kludge to support broken linux IPX stack */
94 /* need to convert dynamic socket open into a real socket number */
96 mprintf((1,"IPX: using socket %x\n", nextDynamicSocket));
97 port = nextDynamicSocket++;
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)
105 mprintf((1,"IPX: could not open IPX socket.\n"));
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"));
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);
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"));
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 );
139 // port = htons(ipxs2.sa_socket);
140 // //n_printf("IPX: opened dynamic socket %04x\n", port);
143 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
144 mprintf((1,"IPX: could not get socket name in IPXOpenSocket\n"));
149 port = htons(ipxs2.sa_socket);
150 mprintf((1,"IPX: opened dynamic socket %04x\n", port));
153 memcpy(ipx_MyAddress, ipxs2.sa_netnum, 4);
154 memcpy(ipx_MyAddress + 4, ipxs2.sa_nodenum, 6);
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);
167 static int ipx_win_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader,
168 u_char *data, int dataLen) {
169 struct sockaddr_ipx ipxs;
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];
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));
189 static int ipx_win_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize,
190 struct ipx_recv_data *rd) {
192 struct sockaddr_ipx ipxs;
195 if ((size = recvfrom(s->fd, buffer, bufsize, 0,
196 (struct sockaddr *) &ipxs, &sz)) <= 0)
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;
207 struct ipx_driver ipx_win = {
208 ipx_win_GetMyAddress,
212 ipx_win_ReceivePacket,
213 ipx_general_PacketReady,
214 NULL, // InitNetgameAuxData
215 NULL, // HandleNetgameAuxData
216 NULL, // HandleLeaveGame