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"
36 #ifdef HAVE_SYS_FILE_H
37 # include <sys/file.h>
39 #ifdef HAVE_SYS_IOCTL_H
40 # include <sys/ioctl.h>
42 #ifdef HAVE_SYS_SOCKET_H
43 # include <sys/socket.h>
45 #ifdef HAVE_SYS_SOCKIO_H
46 # include <sys/sockio.h>
51 #ifdef HAVE_NETINET_IN_H
52 # include <netinet/in.h>
55 #ifdef HAVE_SOCKADDR_SA_LEN
57 # define max(a,b) ((a) > (b) ? (a) : (b))
59 # define ifreq_size(i) max(sizeof(struct ifreq),\
60 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
62 # define ifreq_size(i) sizeof(struct ifreq)
63 # endif /* defined(HAVE_SOCKADDR_SA_LEN) */
65 WINE_DEFAULT_DEBUG_CHANNEL(netbios
);
67 HMODULE NETAPI32_hModule
= 0;
72 unsigned char address
[6];
75 static struct NetBiosAdapter NETBIOS_Adapter
[MAX_LANA
];
78 int get_hw_address(int sd
, struct ifreq
*ifr
, unsigned char *address
)
80 if (ioctl(sd
, SIOCGIFHWADDR
, ifr
) < 0)
82 memcpy(address
, (unsigned char *)&ifr
->ifr_hwaddr
.sa_data
, 6);
87 int get_hw_address(int sd
, struct ifreq
*ifr
, unsigned char *address
)
89 if (ioctl(sd
, SIOCGENADDR
, ifr
) < 0)
91 memcpy(address
, (unsigned char *) ifr
->ifr_enaddr
, 6);
95 int get_hw_address(int sd
, struct ifreq
*ifr
, unsigned char *address
)
99 # endif /* SIOCGENADDR */
100 # endif /* SIOCGIFHWADDR */
102 static UCHAR
NETBIOS_Enum(PNCB ncb
)
106 struct ifreq ifr
, *ifrp
;
108 unsigned char buf
[1024];
111 LANA_ENUM
*lanas
= (PLANA_ENUM
) ncb
->ncb_buffer
;
118 /* BSD 4.4 defines the size of an ifreq to be
119 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
120 * However, under earlier systems, sa_len isn't present, so
121 * the size is just sizeof(struct ifreq)
124 sd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
126 return NRC_OPENERROR
;
128 memset(buf
, 0, sizeof(buf
));
129 ifc
.ifc_len
= sizeof(buf
);
131 /* get the ifconf interface */
132 if (ioctl (sd
, SIOCGIFCONF
, (char *)&ifc
) < 0)
135 return NRC_OPENERROR
;
138 /* loop through the interfaces, looking for a valid one */
139 /* n = ifc.ifc_len; */
141 for (i
= 0; i
< ifc
.ifc_len
; i
++)
143 unsigned char *a
= NETBIOS_Adapter
[i
].address
;
145 ifrp
= (struct ifreq
*)((char *)ifc
.ifc_buf
+ofs
);
146 strncpy(ifr
.ifr_name
, ifrp
->ifr_name
, IFNAMSIZ
);
148 /* try to get the address for this interface */
149 if(get_hw_address(sd
, &ifr
, a
)==0)
151 /* make sure it's not blank */
152 /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
155 TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i
,
156 a
[0],a
[1],a
[2],a
[3],a
[4],a
[5]);
158 NETBIOS_Adapter
[i
].valid
= TRUE
;
159 lanas
->lana
[lanas
->length
] = i
;
162 ofs
+= ifreq_size(ifr
);
165 #endif /* HAVE_NET_IF_H */
170 static UCHAR
NETBIOS_Astat(PNCB ncb
)
172 struct NetBiosAdapter
*nad
= &NETBIOS_Adapter
[ncb
->ncb_lana_num
];
173 PADAPTER_STATUS astat
= (PADAPTER_STATUS
) ncb
->ncb_buffer
;
175 TRACE("NCBASTAT (Adapter %d)\n", ncb
->ncb_lana_num
);
178 return NRC_INVADDRESS
;
180 memset(astat
, 0, sizeof astat
);
181 memcpy(astat
->adapter_address
, nad
->address
, sizeof astat
->adapter_address
);
186 BOOL WINAPI
DllMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
188 TRACE("%p,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
191 case DLL_PROCESS_ATTACH
:
192 NETAPI32_hModule
= hinstDLL
;
194 case DLL_PROCESS_DETACH
:
201 BOOL WINAPI
Netbios(PNCB pncb
)
203 UCHAR ret
= NRC_ILLCMD
;
205 TRACE("ncb = %p\n",pncb
);
208 return NRC_INVADDRESS
;
210 switch(pncb
->ncb_command
&0x7f)
213 FIXME("NCBRESET adapter %d\n",pncb
->ncb_lana_num
);
214 if( (pncb
->ncb_lana_num
< MAX_LANA
) &&
215 NETBIOS_Adapter
[pncb
->ncb_lana_num
].valid
)
218 ret
= NRC_ILLCMD
; /* NetBIOS emulator not found */
222 FIXME("NCBADDNAME\n");
226 FIXME("NCBADDGRNAME\n");
230 FIXME("NCBDELNAME\n");
242 FIXME("NCBHANGUP\n");
246 FIXME("NCBCANCEL\n");
250 FIXME("NCBLISTEN\n");
254 ret
= NETBIOS_Astat(pncb
);
258 ret
= NETBIOS_Enum(pncb
);
262 FIXME("(%p): command code %02x\n", pncb
, pncb
->ncb_command
);
264 ret
= NRC_ILLCMD
; /* NetBIOS emulator not found */
266 pncb
->ncb_retcode
= ret
;