2 * Copyright 2001 Mike McCormack
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "wine/debug.h"
37 #ifdef HAVE_SYS_FILE_H
38 # include <sys/file.h>
40 #ifdef HAVE_SYS_IOCTL_H
41 # include <sys/ioctl.h>
43 #ifdef HAVE_SYS_SOCKET_H
44 # include <sys/socket.h>
46 #ifdef HAVE_SYS_SOCKIO_H
47 # include <sys/sockio.h>
52 #ifdef HAVE_NETINET_IN_H
53 # include <netinet/in.h>
56 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
58 # define max(a,b) ((a) > (b) ? (a) : (b))
60 # define ifreq_size(i) max(sizeof(struct ifreq),\
61 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
63 # define ifreq_size(i) sizeof(struct ifreq)
64 # endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
66 WINE_DEFAULT_DEBUG_CHANNEL(netbios);
68 HMODULE NETAPI32_hModule = 0;
73 unsigned char address[6];
76 static struct NetBiosAdapter NETBIOS_Adapter[MAX_LANA];
79 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
81 if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0)
83 memcpy(address, (unsigned char *)&ifr->ifr_hwaddr.sa_data, 6);
88 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
90 if (ioctl(sd, SIOCGENADDR, ifr) < 0)
92 memcpy(address, (unsigned char *) ifr->ifr_enaddr, 6);
96 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
100 # endif /* SIOCGENADDR */
101 # endif /* SIOCGIFHWADDR */
108 struct ifreq ifr, *ifrp;
110 unsigned char buf[1024];
112 /* BSD 4.4 defines the size of an ifreq to be
113 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
114 * However, under earlier systems, sa_len isn't present, so
115 * the size is just sizeof(struct ifreq)
118 sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
120 return NRC_OPENERROR;
122 memset(buf, 0, sizeof(buf));
123 ifc.ifc_len = sizeof(buf);
125 /* get the ifconf interface */
126 if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
129 return NRC_OPENERROR;
132 /* loop through the interfaces, looking for a valid one */
133 /* n = ifc.ifc_len; */
135 for (i = 0; i < ifc.ifc_len; i++)
137 unsigned char *a = NETBIOS_Adapter[i].address;
139 ifrp = (struct ifreq *)((char *)ifc.ifc_buf+ofs);
140 strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
142 /* try to get the address for this interface */
143 if(get_hw_address(sd, &ifr, a)==0)
145 /* make sure it's not blank */
146 /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
149 TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i,
150 a[0],a[1],a[2],a[3],a[4],a[5]);
152 NETBIOS_Adapter[i].valid = TRUE;
156 ofs += ifreq_size(ifr);
159 TRACE("found %d adapters\n",ret);
160 #endif /* HAVE_NET_IF_H */
164 void wprint_mac(WCHAR* buffer, int index)
168 for (i = 0; i<6; i++)
170 val = NETBIOS_Adapter[index].address[i];
172 buffer[2*i] = (WCHAR)((val >>4) + 'A' - 10);
174 buffer[2*i] = (WCHAR)((val >>4) + '0');
176 buffer[2*i+1] = (WCHAR)((val & 0xf) + 'A' - 10);
178 buffer[2*i+1] = (WCHAR)((val & 0xf) + '0');
183 static UCHAR NETBIOS_Enum(PNCB ncb)
186 LANA_ENUM *lanas = (PLANA_ENUM) ncb->ncb_buffer;
191 for (i = 0; i < enum_hw(); i++)
193 lanas->lana[lanas->length] = i;
200 static UCHAR NETBIOS_Astat(PNCB ncb)
202 struct NetBiosAdapter *nad = &NETBIOS_Adapter[ncb->ncb_lana_num];
203 PADAPTER_STATUS astat = (PADAPTER_STATUS) ncb->ncb_buffer;
205 TRACE("NCBASTAT (Adapter %d)\n", ncb->ncb_lana_num);
208 return NRC_INVADDRESS;
210 memset(astat, 0, sizeof astat);
211 memcpy(astat->adapter_address, nad->address, sizeof astat->adapter_address);
216 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
218 TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
221 case DLL_PROCESS_ATTACH:
222 NETAPI32_hModule = hinstDLL;
224 case DLL_PROCESS_DETACH:
231 BOOL WINAPI Netbios(PNCB pncb)
233 UCHAR ret = NRC_ILLCMD;
235 TRACE("ncb = %p\n",pncb);
238 return NRC_INVADDRESS;
240 switch(pncb->ncb_command&0x7f)
243 FIXME("NCBRESET adapter %d\n",pncb->ncb_lana_num);
244 if( (pncb->ncb_lana_num < MAX_LANA ) &&
245 NETBIOS_Adapter[pncb->ncb_lana_num].valid)
248 ret = NRC_ILLCMD; /* NetBIOS emulator not found */
252 FIXME("NCBADDNAME\n");
256 FIXME("NCBADDGRNAME\n");
260 FIXME("NCBDELNAME\n");
272 FIXME("NCBHANGUP\n");
276 FIXME("NCBCANCEL\n");
280 FIXME("NCBLISTEN\n");
284 ret = NETBIOS_Astat(pncb);
288 ret = NETBIOS_Enum(pncb);
292 FIXME("(%p): command code %02x\n", pncb, pncb->ncb_command);
294 ret = NRC_ILLCMD; /* NetBIOS emulator not found */
296 pncb->ncb_retcode = ret;
300 NET_API_STATUS WINAPI NetServerEnum(
306 LPDWORD totalentries,
309 LPDWORD resume_handle
312 FIXME("Stub (%p, %ld %p %ld %p %p %ld %s %p)\n",servername, level, bufptr,
313 prefmaxlen, entriesread, totalentries, servertype, debugstr_w(domain), resume_handle);
315 return ERROR_NO_BROWSER_SERVERS_FOUND;