add IPv4 multicasting support
[btb/d2x.git] / arch / linux / ipx_kali.c
1 /* $Id: ipx_kali.c,v 1.6 2003-10-12 09:17:47 btb Exp $ */
2 /*
3  *
4  * IPX driver for KaliNix interface
5  *
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <conf.h>
10 #endif
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <netinet/in.h> /* for htons & co. */
15 #include "ipx_drv.h"
16 #include "ukali.h"
17
18 extern unsigned char ipx_MyAddress[10];
19
20 static int open_sockets = 0;
21 static int dynamic_socket = 0x401;
22 static int last_socket = 0;
23
24 int have_empty_address() {
25         int i;
26         for (i = 0; i < 10 && !ipx_MyAddress[i]; i++) ;
27         return i == 10;
28 }
29
30 int ipx_kali_GetMyAddress(void)
31 {
32
33         kaliaddr_ipx mKaliAddr;
34
35         if (!have_empty_address())
36                 return 0;
37
38         if (KaliGetNodeNum(&mKaliAddr) < 0)
39                 return -1;
40
41         memset(ipx_MyAddress, 0, 4);
42         memcpy(ipx_MyAddress + 4, mKaliAddr.sa_nodenum, sizeof(mKaliAddr.sa_nodenum));
43
44         return 0;
45 }
46
47 int ipx_kali_OpenSocket(ipx_socket_t *sk, int port)
48 {
49         printf("IPX_kali: OpenSocket on port(%d)\n", port);
50
51         if (!open_sockets) {
52                 if (have_empty_address()) {
53                         if (ipx_kali_GetMyAddress() < 0) {
54                                 printf("IPX_kali: Error communicating with KaliNix\n");
55                                 return -1;
56                         }
57                 }
58         }
59         if (!port)
60                 port = dynamic_socket++;
61
62         if ((sk->fd = KaliOpenSocket(htons(port))) < 0) {
63                 printf("IPX_kali: OpenSocket Failed on port(%d)\n", port);
64                 sk->fd = -1;
65                 return -1;
66         }
67         open_sockets++;
68         last_socket = port;
69         sk->socket = port;
70         return 0;
71 }
72
73 void ipx_kali_CloseSocket(ipx_socket_t *mysock)
74 {
75         if (!open_sockets) {
76                 printf("IPX_kali: close w/o open\n");
77                 return;
78         }
79         printf("IPX_kali: CloseSocket on port(%d)\n", mysock->socket);
80         KaliCloseSocket(mysock->fd);
81         if (--open_sockets) {
82                 printf("IPX_kali: (closesocket) %d sockets left\n", open_sockets);
83                 return;
84         }
85 }
86
87 int ipx_kali_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader,
88  u_char *data, int dataLen)
89 {
90         kaliaddr_ipx toaddr;
91         int i;
92
93         memcpy(toaddr.sa_nodenum, IPXHeader->Destination.Node, sizeof(toaddr.sa_nodenum));
94         memcpy(&toaddr.sa_socket, IPXHeader->Destination.Socket, sizeof(toaddr.sa_socket));
95
96         if ((i = KaliSendPacket(mysock->fd, (char *)data, dataLen, &toaddr)) < 0)
97                 return -1;
98
99         return i;
100 }
101
102 int ipx_kali_ReceivePacket(ipx_socket_t *s, char *outbuf, int outbufsize,
103  struct ipx_recv_data *rd)
104 {
105         int size;
106         kaliaddr_ipx fromaddr;
107
108         if ((size = KaliReceivePacket(s->fd, outbuf, outbufsize, &fromaddr)) < 0)
109                 return -1;
110
111         rd->dst_socket = s->socket;
112         rd->src_socket = ntohs(fromaddr.sa_socket);
113         memcpy(rd->src_node, fromaddr.sa_nodenum, sizeof(fromaddr.sa_nodenum));
114         memset(rd->src_network, 0, 4);
115         rd->pkt_type = 0;
116
117         return size;
118 }
119
120 struct ipx_driver ipx_kali = {
121         ipx_kali_GetMyAddress,
122         ipx_kali_OpenSocket,
123         ipx_kali_CloseSocket,
124         ipx_kali_SendPacket,
125         ipx_kali_ReceivePacket,
126         ipx_general_PacketReady,
127         NULL,   // InitNetgameAuxData
128         NULL,   // HandleNetgameAuxData
129         NULL,   // HandleLeaveGame
130         NULL    // SendGamePacket
131 };