Fix a couple of warnings and a typo.
[wine] / dlls / netapi32 / netapi32.c
1 /*              
2  * Copyright 2001 Mike McCormack
3  */
4
5 #include "config.h"
6
7 #include <string.h>
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11
12 #include "winbase.h"
13 #include "winreg.h"
14 #include "wingdi.h"
15 #include "winuser.h"
16 #include "debugtools.h"
17 #include "winerror.h"
18 #include "nb30.h"
19
20 #ifdef HAVE_SYS_FILE_H
21 # include <sys/file.h>
22 #endif
23 #include <sys/ioctl.h>
24 #ifdef HAVE_SYS_SOCKET_H
25 # include <sys/socket.h>
26 #endif
27 #ifdef HAVE_SYS_SOCKIO_H
28 # include <sys/sockio.h>
29 #endif
30 #ifdef HAVE_NET_IF_H
31 # include <net/if.h>
32 #endif
33 #ifdef HAVE_NETINET_IN_H
34 # include <netinet/in.h>
35 #endif
36
37 #ifdef HAVE_SOCKADDR_SA_LEN
38 #  ifndef max
39 #   define max(a,b) ((a) > (b) ? (a) : (b))
40 #  endif
41 #  define ifreq_size(i) max(sizeof(struct ifreq),\
42 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
43 # else
44 #  define ifreq_size(i) sizeof(struct ifreq)
45 # endif /* defined(HAVE_SOCKADDR_SA_LEN) */
46
47 DEFAULT_DEBUG_CHANNEL(netbios);
48
49 HMODULE NETAPI32_hModule = 0;
50
51 struct NetBiosAdapter
52 {
53     int valid;
54     unsigned char address[6];
55 };
56
57 static struct NetBiosAdapter NETBIOS_Adapter[MAX_LANA];
58
59 # ifdef SIOCGIFHWADDR
60 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
61 {
62     if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0)
63         return -1;
64     memcpy(address, (unsigned char *)&ifr->ifr_hwaddr.sa_data, 6);
65     return 0;
66 }
67 # else
68 #  ifdef SIOCGENADDR
69 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
70 {
71     if (ioctl(sd, SIOCGENADDR, ifr) < 0)
72         return -1;
73     memcpy(address, (unsigned char *) ifr->ifr_enaddr, 6);
74     return 0;
75 }
76 #   else
77 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
78 {
79     return -1;
80 }
81 #  endif /* SIOCGENADDR */
82 # endif /* SIOCGIFHWADDR */
83
84 static UCHAR NETBIOS_Enum(PNCB ncb)
85 {
86 #ifdef HAVE_NET_IF_H
87     int             sd;
88     struct ifreq    ifr, *ifrp;
89     struct ifconf   ifc;
90     unsigned char   buf[1024];
91     int             i, ofs;
92 #endif
93     LANA_ENUM *lanas = (PLANA_ENUM) ncb->ncb_buffer;
94
95     TRACE("NCBENUM\n");
96
97     lanas->length = 0;
98
99 #ifdef HAVE_NET_IF_H
100     /* BSD 4.4 defines the size of an ifreq to be
101      * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
102      * However, under earlier systems, sa_len isn't present, so
103      *  the size is just sizeof(struct ifreq)
104      */
105
106     sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
107     if (sd < 0)
108         return NRC_OPENERROR;
109
110     memset(buf, 0, sizeof(buf));
111     ifc.ifc_len = sizeof(buf);
112     ifc.ifc_buf = buf;
113     /* get the ifconf interface */
114     if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
115     {
116         close(sd);
117         return NRC_OPENERROR;
118     }
119
120     /* loop through the interfaces, looking for a valid one */
121     /* n = ifc.ifc_len; */
122     ofs = 0;
123     for (i = 0; i < ifc.ifc_len; i++)
124     {
125         unsigned char *a = NETBIOS_Adapter[i].address;
126
127         ifrp = (struct ifreq *)((char *)ifc.ifc_buf+ofs);
128         strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
129
130         /* try to get the address for this interface */
131         if(get_hw_address(sd, &ifr, a)==0)
132         {
133             /* make sure it's not blank */
134             /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
135                 continue; */
136
137             TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i,
138                         a[0],a[1],a[2],a[3],a[4],a[5]);
139
140             NETBIOS_Adapter[i].valid = TRUE;
141             lanas->lana[lanas->length] = i;
142             lanas->length++;
143         }
144         ofs += ifreq_size(ifr);
145     }
146     close(sd);
147 #endif /* HAVE_NET_IF_H */
148     return NRC_GOODRET;
149 }
150
151
152 static UCHAR NETBIOS_Astat(PNCB ncb)
153 {
154     struct NetBiosAdapter *nad = &NETBIOS_Adapter[ncb->ncb_lana_num];
155     PADAPTER_STATUS astat = (PADAPTER_STATUS) ncb->ncb_buffer;
156
157     TRACE("NCBASTAT (Adapter %d)\n", ncb->ncb_lana_num);
158
159     if(!nad->valid)
160         return NRC_INVADDRESS;
161
162     memset(astat, 0, sizeof astat);
163     memcpy(astat->adapter_address, nad->address, sizeof astat->adapter_address);
164
165     return NRC_GOODRET;
166 }
167
168 BOOL WINAPI
169 NETAPI32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
170 {
171     TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
172
173     switch (fdwReason) {
174         case DLL_PROCESS_ATTACH:
175             NETAPI32_hModule = hinstDLL;
176             break;
177         case DLL_PROCESS_DETACH:
178             break;
179     }
180
181     return TRUE;
182 }
183
184 BOOL WINAPI Netbios(PNCB pncb)
185 {
186     UCHAR ret = NRC_ILLCMD; 
187
188     TRACE("ncb = %p\n",pncb);
189
190     if(!pncb)
191         return NRC_INVADDRESS;
192
193     switch(pncb->ncb_command&0x7f)
194     {
195     case NCBRESET:
196         FIXME("NCBRESET adapter %d\n",pncb->ncb_lana_num);
197         if( (pncb->ncb_lana_num < MAX_LANA ) && 
198              NETBIOS_Adapter[pncb->ncb_lana_num].valid)
199             ret = NRC_GOODRET;
200         else
201             ret = NRC_ILLCMD; /* NetBIOS emulator not found */
202         break;
203
204     case NCBADDNAME:
205         FIXME("NCBADDNAME\n");
206         break;
207
208     case NCBADDGRNAME:
209         FIXME("NCBADDGRNAME\n");
210         break;
211
212     case NCBDELNAME:
213         FIXME("NCBDELNAME\n");
214         break;
215
216     case NCBSEND:
217         FIXME("NCBSEND\n");
218         break;
219
220     case NCBRECV:
221         FIXME("NCBRECV\n");
222         break;
223
224     case NCBHANGUP:
225         FIXME("NCBHANGUP\n");
226         break;
227
228     case NCBCANCEL:
229         FIXME("NCBCANCEL\n");
230         break;
231
232     case NCBLISTEN:
233         FIXME("NCBLISTEN\n");
234         break;
235
236     case NCBASTAT:
237         ret = NETBIOS_Astat(pncb);
238         break;
239
240     case NCBENUM:
241         ret = NETBIOS_Enum(pncb);
242         break;
243
244     default:
245         FIXME("(%p): command code %02x\n", pncb, pncb->ncb_command);
246
247         ret = NRC_ILLCMD; /* NetBIOS emulator not found */
248     }
249     pncb->ncb_retcode = ret;
250     return ret;
251 }
252