2 * $Source: /cvs/cvsroot/d2x/arch/linux/ipx_bsd.c,v $
5 * $Date: 2001-10-19 07:39:25 $
7 * IPX driver using BSD style sockets
8 * Mostly taken from dosemu
10 * $Log: not supported by cvs2svn $
11 * Revision 1.3 2001/10/19 07:29:36 bradleyb
12 * Brought linux networking in line with d1x, moved some arch/linux_* stuff to arch/linux/
14 * Revision 1.2 2001/01/29 13:35:08 bradleyb
15 * Fixed build system, minor fixes
23 #include <sys/types.h>
24 #include <sys/socket.h>
27 #ifdef HAVE_NETIPX_IPX_H
28 #include <netipx/ipx.h>
30 # include <linux/ipx.h>
36 #include <netinet/in.h>
45 #define n_printf(format, args...) mprintf((1, format, ## args))
46 #define enter_priv_on()
47 #define leave_priv_setting()
50 static ipx_socket_t mysock;
52 static int ipx_bsd_GetMyAddress( void )
55 struct sockaddr_ipx ipxs;
56 struct sockaddr_ipx ipxs2;
60 sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
63 n_printf("IPX: could not open socket in GetMyAddress\n");
67 /* bind this socket to network 0 */
68 ipxs.sipx_family=AF_IPX;
69 #ifdef IPX_MANUAL_ADDRESS
70 memcpy(&ipxs.sipx_network, ipx_MyAddress, 4);
76 if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1)
78 n_printf("IPX: could bind to network 0 in GetMyAddress\n");
84 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
85 n_printf("IPX: could not get socket name in GetMyAddress\n");
90 memcpy(ipx_MyAddress, &ipxs2.sipx_network, 4);
91 for (i = 0; i < 6; i++) {
92 ipx_MyAddress[4+i] = ipxs2.sipx_node[i];
98 static int ipx_bsd_OpenSocket(int port)
100 int sock; /* sock here means Linux socket handle */
102 struct sockaddr_ipx ipxs;
104 struct sockaddr_ipx ipxs2;
106 /* DANG_FIXTHIS - kludge to support broken linux IPX stack */
107 /* need to convert dynamic socket open into a real socket number */
109 n_printf("IPX: using socket %x\n", nextDynamicSocket);
110 port = nextDynamicSocket++;
113 /* do a socket call, then bind to this port */
114 sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
116 n_printf("IPX: could not open IPX socket.\n");
122 /* turn on socket debugging */
125 if (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &opt, sizeof(opt)) == -1) {
126 leave_priv_setting();
127 n_printf("IPX: could not set socket option for debugging.\n");
130 leave_priv_setting();
134 /* Permit broadcast output */
136 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
137 &opt, sizeof(opt)) == -1) {
138 leave_priv_setting();
139 n_printf("IPX: could not set socket option for broadcast.\n");
143 /* allow setting the type field in the IPX header */
145 #if 0 /* this seems to be wrong: IPX_TYPE can only be set on level SOL_IPX */
146 if (setsockopt(sock, SOL_SOCKET, IPX_TYPE, &opt, sizeof(opt)) == -1) {
148 /* the socket _is_ an IPX socket, hence it first passes ipx_setsockopt()
149 * in file linux/net/ipx/af_ipx.c. This one handles SOL_IPX itself and
150 * passes SOL_SOCKET-levels down to sock_setsockopt().
151 * Hence I guess the below is correct (can somebody please verify this?)
152 * -- Hans, June 14 1997
154 if (setsockopt(sock, SOL_IPX, IPX_TYPE, &opt, sizeof(opt)) == -1) {
156 leave_priv_setting();
157 n_printf("IPX: could not set socket option for type.\n");
161 ipxs.sipx_family = AF_IPX;
162 ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]);
163 /* ipxs.sipx_network = htonl(MyNetwork); */
164 bzero(ipxs.sipx_node, 6); /* Please fill in my node name */
165 ipxs.sipx_port = htons(port);
167 /* now bind to this port */
168 if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) {
169 n_printf("IPX: could not bind socket to address\n");
171 leave_priv_setting();
177 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
178 n_printf("IPX: could not get socket name in IPXOpenSocket\n");
180 leave_priv_setting();
183 port = htons(ipxs2.sipx_port);
184 n_printf("IPX: opened dynamic socket %04x\n", port);
187 leave_priv_setting();
189 mysock.socket = port;
191 ipx_bsd_GetMyAddress();
196 static void ipx_bsd_CloseSocket(void) {
197 /* now close the file descriptor for the socket, and free it */
198 n_printf("IPX: closing file descriptor on socket %x\n", mysock.socket);
202 static int ipx_bsd_SendPacket(IPXPacket_t *IPXHeader,
203 u_char *data, int dataLen) {
204 struct sockaddr_ipx ipxs;
206 ipxs.sipx_family = AF_IPX;
207 /* get destination address from IPX packet header */
208 memcpy(&ipxs.sipx_network, IPXHeader->Destination.Network, 4);
209 /* if destination address is 0, then send to my net */
210 if (ipxs.sipx_network == 0) {
211 ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]);
212 /* ipxs.sipx_network = htonl(MyNetwork); */
214 memcpy(&ipxs.sipx_node, IPXHeader->Destination.Node, 6);
215 //memcpy(&ipxs.sipx_port, IPXHeader->Destination.Socket, 2);
216 ipxs.sipx_port=htons(mysock.socket);
217 ipxs.sipx_type = IPXHeader->PacketType;
218 /* ipxs.sipx_port=htons(0x452); */
219 return sendto(mysock.fd, data, dataLen, 0,
220 (struct sockaddr *) &ipxs, sizeof(ipxs));
223 static int ipx_bsd_ReceivePacket(char *buffer, int bufsize,
224 struct ipx_recv_data *rd) {
226 struct sockaddr_ipx ipxs;
229 if ((size = recvfrom(mysock.fd, buffer, bufsize, 0,
230 (struct sockaddr *) &ipxs, &sz)) <= 0)
232 memcpy(rd->src_network, &ipxs.sipx_network, 4);
233 memcpy(rd->src_node, ipxs.sipx_node, 6);
234 rd->src_socket = ipxs.sipx_port;
235 rd->dst_socket = mysock.socket;
236 rd->pkt_type = ipxs.sipx_type;
241 static int ipx_bsd_general_PacketReady(void) {
242 return ipx_general_PacketReady(mysock.fd);
245 struct ipx_driver ipx_bsd = {
246 // ipx_bsd_GetMyAddress,
250 ipx_bsd_ReceivePacket,
251 ipx_bsd_general_PacketReady,