2 * $Source: /cvs/cvsroot/d2x/arch/linux/ipx_lin.c,v $
5 * $Date: 2001-10-19 07:29:37 $
9 * $Log: not supported by cvs2svn $
10 * Revision 1.2 2001/01/29 13:35:08 bradleyb
11 * Fixed build system, minor fixes
20 #include <sys/types.h>
21 #include <sys/socket.h>
24 #ifdef HAVE_NETIPX_IPX_H
25 #include <netipx/ipx.h>
27 # include <linux/ipx.h>
33 #include <netinet/in.h>
42 extern unsigned char ipx_MyAddress[10];
45 ipx_linux_GetMyAddress( void )
48 struct sockaddr_ipx ipxs;
49 struct sockaddr_ipx ipxs2;
53 sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX);
56 n_printf("IPX: could not open socket in GetMyAddress\n");
60 /* bind this socket to network 0 */
61 ipxs.sipx_family=AF_IPX;
62 #ifdef IPX_MANUAL_ADDRESS
63 memcpy(&ipxs.sipx_network, ipx_MyAddress, 4);
69 if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1)
71 n_printf("IPX: could bind to network 0 in GetMyAddress\n");
77 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
78 n_printf("IPX: could not get socket name in GetMyAddress\n");
83 memcpy(ipx_MyAddress, &ipxs2.sipx_network, 4);
84 for (i = 0; i < 6; i++) {
85 ipx_MyAddress[4+i] = ipxs2.sipx_node[i];
92 ipx_linux_OpenSocket(ipx_socket_t *sk, int port)
94 int sock; /* sock here means Linux socket handle */
96 struct sockaddr_ipx ipxs;
98 struct sockaddr_ipx ipxs2;
100 /* DANG_FIXTHIS - kludge to support broken linux IPX stack */
101 /* need to convert dynamic socket open into a real socket number */
103 n_printf("IPX: using socket %x\n", nextDynamicSocket);
104 port = nextDynamicSocket++;
107 /* do a socket call, then bind to this port */
108 sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
110 n_printf("IPX: could not open IPX socket.\n");
116 /* turn on socket debugging */
119 if (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &opt, sizeof(opt)) == -1) {
120 leave_priv_setting();
121 n_printf("IPX: could not set socket option for debugging.\n");
124 leave_priv_setting();
128 /* Permit broadcast output */
130 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
131 &opt, sizeof(opt)) == -1) {
132 leave_priv_setting();
133 n_printf("IPX: could not set socket option for broadcast.\n");
137 /* allow setting the type field in the IPX header */
139 #if 0 /* this seems to be wrong: IPX_TYPE can only be set on level SOL_IPX */
140 if (setsockopt(sock, SOL_SOCKET, IPX_TYPE, &opt, sizeof(opt)) == -1) {
142 /* the socket _is_ an IPX socket, hence it first passes ipx_setsockopt()
143 * in file linux/net/ipx/af_ipx.c. This one handles SOL_IPX itself and
144 * passes SOL_SOCKET-levels down to sock_setsockopt().
145 * Hence I guess the below is correct (can somebody please verify this?)
146 * -- Hans, June 14 1997
148 if (setsockopt(sock, SOL_IPX, IPX_TYPE, &opt, sizeof(opt)) == -1) {
150 leave_priv_setting();
151 n_printf("IPX: could not set socket option for type.\n");
155 ipxs.sipx_family = AF_IPX;
156 ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]);
157 /* ipxs.sipx_network = htonl(MyNetwork); */
158 bzero(ipxs.sipx_node, 6); /* Please fill in my node name */
159 ipxs.sipx_port = htons(port);
161 /* now bind to this port */
162 if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) {
163 n_printf("IPX: could not bind socket to address\n");
165 leave_priv_setting();
171 if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) {
172 n_printf("IPX: could not get socket name in IPXOpenSocket\n");
174 leave_priv_setting();
177 port = htons(ipxs2.sipx_port);
178 n_printf("IPX: opened dynamic socket %04x\n", port);
181 leave_priv_setting();
187 void ipx_linux_CloseSocket(ipx_socket_t *mysock) {
188 /* now close the file descriptor for the socket, and free it */
189 n_printf("IPX: closing file descriptor on socket %x\n", mysock->socket);
193 int ipx_linux_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader,
194 u_char *data, int dataLen) {
195 struct sockaddr_ipx ipxs;
197 ipxs.sipx_family = AF_IPX;
198 /* get destination address from IPX packet header */
199 memcpy(&ipxs.sipx_network, IPXHeader->Destination.Network, 4);
200 /* if destination address is 0, then send to my net */
201 if (ipxs.sipx_network == 0) {
202 ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]);
203 /* ipxs.sipx_network = htonl(MyNetwork); */
205 memcpy(&ipxs.sipx_node, IPXHeader->Destination.Node, 6);
206 memcpy(&ipxs.sipx_port, IPXHeader->Destination.Socket, 2);
207 ipxs.sipx_type = IPXHeader->PacketType;
208 /* ipxs.sipx_port=htons(0x452); */
209 return sendto(mysock->fd, data, dataLen, 0,
210 (struct sockaddr *) &ipxs, sizeof(ipxs));
213 int ipx_linux_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize,
214 struct ipx_recv_data *rd) {
216 struct sockaddr_ipx ipxs;
219 if ((size = recvfrom(s->fd, buffer, bufsize, 0,
220 (struct sockaddr *) &ipxs, &sz)) <= 0)
222 memcpy(rd->src_network, &ipxs.sipx_network, 4);
223 memcpy(rd->src_node, ipxs.sipx_node, 6);
224 rd->src_socket = ipxs.sipx_port;
225 rd->dst_socket = s->socket;
226 rd->pkt_type = ipxs.sipx_type;