2 * Utility routines for packet capture
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
40 #ifdef HAVE_SYS_SOCKET_H
41 #include <sys/socket.h>
47 #include "capture_ifinfo.h"
48 #include "capture-pcap-util.h"
49 #include "capture-pcap-util-int.h"
51 #include "wsutil/file_util.h"
54 #include <netinet/in.h>
58 #include "capture_win_ifnames.h" /* windows friendly interface names */
62 * Given an interface name, find the "friendly name" and interface
63 * type for the interface.
66 #if defined(__APPLE__)
68 #include <CoreFoundation/CoreFoundation.h>
69 #include <SystemConfiguration/SystemConfiguration.h>
74 * On OS X, we get the "friendly name" and interface type for the interface
75 * from the System Configuration framework.
77 * To find the System Configuration framework information for the
78 * interface, we get all the interfaces that the System Configuration
79 * framework knows about and look for the one with a "BSD name" matching
82 * If we find it, we use its "localized display name", if it has one, as
83 * the "friendly name".
85 * As for the interface type:
87 * Yes, fetching all the network addresses for an interface gets you an
88 * AF_LINK address, of type "struct sockaddr_dl", and, yes, that includes
89 * an SNMP MIB-II ifType value.
91 * However, it's IFT_ETHER, i.e. Ethernet, for AirPort interfaces,
92 * not IFT_IEEE80211 (which isn't defined in OS X in any case).
94 * Perhaps some other BSD-flavored OSes won't make this mistake;
95 * however, FreeBSD 7.0 and OpenBSD 4.2, at least, appear to have
96 * made the same mistake, at least for my Belkin ZyDAS stick.
98 * SCNetworkInterfaceGetInterfaceType() will get the interface
99 * type. The interface type is a CFString, and:
101 * kSCNetworkInterfaceTypeIEEE80211 means IF_WIRELESS;
102 * kSCNetworkInterfaceTypeBluetooth means IF_BLUETOOTH;
103 * kSCNetworkInterfaceTypeModem or
104 * kSCNetworkInterfaceTypePPP or
105 * maybe kSCNetworkInterfaceTypeWWAN means IF_DIALUP
108 add_unix_interface_ifinfo(if_info_t
*if_info
, const char *name
,
109 const char *description _U_
)
111 CFStringRef name_CFString
;
112 CFArrayRef interfaces
;
113 CFIndex num_interfaces
;
115 SCNetworkInterfaceRef interface
;
116 CFStringRef bsdname_CFString
;
117 CFStringRef friendly_name_CFString
;
118 CFStringRef interface_type_CFString
;
120 interfaces
= SCNetworkInterfaceCopyAll();
121 if (interfaces
== NULL
) {
123 * Couldn't get a list of interfaces.
128 name_CFString
= CFStringCreateWithCString(kCFAllocatorDefault
,
129 name
, kCFStringEncodingUTF8
);
130 if (name_CFString
== NULL
) {
132 * Couldn't convert the interface name to a CFString.
134 CFRelease(interfaces
);
138 num_interfaces
= CFArrayGetCount(interfaces
);
139 for (i
= 0; i
< num_interfaces
; i
++) {
140 interface
= (SCNetworkInterfaceRef
)CFArrayGetValueAtIndex(interfaces
, i
);
141 bsdname_CFString
= SCNetworkInterfaceGetBSDName(interface
);
142 if (bsdname_CFString
== NULL
) {
144 * This interface has no BSD name, so it's not
145 * a regular network interface.
149 if (CFStringCompare(name_CFString
, bsdname_CFString
, 0) == 0) {
151 * This is the interface.
152 * First, get the friendly name.
154 friendly_name_CFString
= SCNetworkInterfaceGetLocalizedDisplayName(interface
);
155 if (friendly_name_CFString
!= NULL
)
156 if_info
->friendly_name
= CFString_to_C_string(friendly_name_CFString
);
159 * Now get the interface type.
161 interface_type_CFString
= SCNetworkInterfaceGetInterfaceType(interface
);
162 if (CFStringCompare(interface_type_CFString
,
163 kSCNetworkInterfaceTypeIEEE80211
, 0) == kCFCompareEqualTo
)
164 if_info
->type
= IF_WIRELESS
;
165 else if (CFStringCompare(interface_type_CFString
,
166 kSCNetworkInterfaceTypeBluetooth
, 0) == kCFCompareEqualTo
)
167 if_info
->type
= IF_BLUETOOTH
;
168 else if (CFStringCompare(interface_type_CFString
,
169 kSCNetworkInterfaceTypeModem
, 0) == kCFCompareEqualTo
)
170 if_info
->type
= IF_DIALUP
;
171 else if (CFStringCompare(interface_type_CFString
,
172 kSCNetworkInterfaceTypePPP
, 0) == kCFCompareEqualTo
)
173 if_info
->type
= IF_DIALUP
;
174 else if (CFStringCompare(interface_type_CFString
,
175 kSCNetworkInterfaceTypeWWAN
, 0) == kCFCompareEqualTo
)
176 if_info
->type
= IF_DIALUP
;
178 if_info
->type
= IF_WIRED
;
183 CFRelease(interfaces
);
184 CFRelease(name_CFString
);
186 #elif defined(__linux__)
188 * Linux doesn't offer any form of "friendly name", but you can
189 * determine an interface type to some degree.
192 add_unix_interface_ifinfo(if_info_t
*if_info
, const char *name
,
193 const char *description _U_
)
199 * Look for /sys/class/net/{device}/wireless. If it exists,
200 * it's a wireless interface.
202 wireless_path
= g_strdup_printf("/sys/class/net/%s/wireless", name
);
203 if (wireless_path
!= NULL
) {
204 if (ws_stat64(wireless_path
, &statb
) == 0)
205 if_info
->type
= IF_WIRELESS
;
206 g_free(wireless_path
);
208 if (if_info
->type
== IF_WIRED
) {
210 * We still don't know what it is. Check for
211 * Bluetooth and USB devices.
213 if (strstr(name
, "bluetooth") != NULL
) {
215 * XXX - this is for raw Bluetooth capture; what
216 * about IP-over-Bluetooth devices?
218 if_info
->type
= IF_BLUETOOTH
;
219 } else if (strstr(name
, "usbmon") != NULL
)
220 if_info
->type
= IF_USB
;
225 * On other UN*Xes, if there is a description, it's a friendly
226 * name, and there is no vendor description. ("Other UN*Xes"
227 * currently means "FreeBSD and OpenBSD".)
230 add_unix_interface_ifinfo(if_info_t
*if_info
, const char *name _U_
,
231 const char *description
)
233 if_info
->friendly_name
= g_strdup(description
);
238 if_info_new(const char *name
, const char *description
, gboolean loopback
)
242 const char *guid_text
;
246 if_info
= (if_info_t
*)g_malloc(sizeof (if_info_t
));
247 if_info
->name
= g_strdup(name
);
248 if_info
->friendly_name
= NULL
; /* default - unknown */
249 if_info
->vendor_description
= NULL
;
250 if_info
->type
= IF_WIRED
; /* default */
253 * Get the interface type.
255 * Much digging failed to reveal any obvious way to get something
256 * such as the SNMP MIB-II ifType value for an interface:
258 * http://www.iana.org/assignments/ianaiftype-mib
260 * by making some NDIS request. And even if there were such
261 * a way, there's no guarantee that the ifType reflects an
262 * interface type that a user would view as correct (for
263 * example, some systems report Wi-Fi interfaces as
264 * Ethernet interfaces).
266 * So we look for keywords in the vendor's interface
269 if (description
&& (strstr(description
, "generic dialup") != NULL
||
270 strstr(description
, "PPP/SLIP") != NULL
)) {
271 if_info
->type
= IF_DIALUP
;
272 } else if (description
&& (strstr(description
, "Wireless") != NULL
||
273 strstr(description
,"802.11") != NULL
)) {
274 if_info
->type
= IF_WIRELESS
;
275 } else if (description
&& strstr(description
, "AirPcap") != NULL
||
276 strstr(name
, "airpcap") != NULL
) {
277 if_info
->type
= IF_AIRPCAP
;
278 } else if (description
&& strstr(description
, "Bluetooth") != NULL
) {
279 if_info
->type
= IF_BLUETOOTH
;
280 } else if (description
&& strstr(description
, "VMware") != NULL
) {
282 * Bridge, NAT, or host-only interface on a VMware host.
284 * XXX - what about guest interfaces?
286 if_info
->type
= IF_VIRTUAL
;
290 * On Windows, the "description" is a vendor description,
291 * and the friendly name isn't returned by WinPcap.
292 * Fetch it ourselves.
296 * Skip over the "\Device\NPF_" prefix in the device name,
299 if (strncmp("\\Device\\NPF_", name
, 12) == 0)
300 guid_text
= name
+ 12;
304 /* Now try to parse what remains as a GUID. */
305 if (parse_as_guid(guid_text
, &guid
)) {
307 * Success. Try to get a friendly name using the GUID.
308 * As this is a regular interface, the description is a
309 * vendor description.
311 if_info
->friendly_name
= get_interface_friendly_name_from_device_guid(&guid
);
312 if_info
->vendor_description
= g_strdup(description
);
315 * This is probably not a regular interface; we only
316 * support NT 5 (W2K) and later, so all regular interfaces
317 * should have GUIDs at the end of the name. Therefore,
318 * the description, if supplied, is a friendly name
319 * provided by WinPcap, and there is no vendor
322 if_info
->friendly_name
= g_strdup(description
);
323 if_info
->vendor_description
= NULL
;
327 * On UN*X, if there is a description, it's a friendly
328 * name, and there is no vendor description.
330 * Try the platform's way of getting a friendly name and
331 * interface type first.
333 * If that fails, then, for a loopback interface, give it the
334 * friendly name "Loopback" and, for VMware interfaces,
335 * give them the type IF_VIRTUAL.
337 add_unix_interface_ifinfo(if_info
, name
, description
);
338 if (if_info
->type
== IF_WIRED
) {
340 * This is the default interface type.
342 * Bridge, NAT, or host-only interfaces on VMWare hosts
343 * have the name vmnet[0-9]+. Guests might use a native
344 * (LANCE or E1000) driver or the vmxnet driver. Check
347 if (g_ascii_strncasecmp(name
, "vmnet", 5) == 0)
348 if_info
->type
= IF_VIRTUAL
;
349 else if (g_ascii_strncasecmp(name
, "vmxnet", 6) == 0)
350 if_info
->type
= IF_VIRTUAL
;
352 if (if_info
->friendly_name
== NULL
) {
354 * We couldn't get interface information using platform-
357 * If this is a loopback interface, give it a
358 * "friendly name" of "Loopback".
361 if_info
->friendly_name
= g_strdup("Loopback");
363 if_info
->vendor_description
= NULL
;
365 if_info
->loopback
= loopback
;
366 if_info
->addrs
= NULL
;
371 if_info_add_address(if_info_t
*if_info
, struct sockaddr
*addr
)
374 struct sockaddr_in
*ai
;
376 struct sockaddr_in6
*ai6
;
379 switch (addr
->sa_family
) {
382 ai
= (struct sockaddr_in
*)(void *)addr
;
383 if_addr
= (if_addr_t
*)g_malloc(sizeof(*if_addr
));
384 if_addr
->ifat_type
= IF_AT_IPv4
;
385 if_addr
->addr
.ip4_addr
=
386 *((guint32
*)&(ai
->sin_addr
.s_addr
));
387 if_info
->addrs
= g_slist_append(if_info
->addrs
, if_addr
);
392 ai6
= (struct sockaddr_in6
*)(void *)addr
;
393 if_addr
= (if_addr_t
*)g_malloc(sizeof(*if_addr
));
394 if_addr
->ifat_type
= IF_AT_IPv6
;
395 memcpy((void *)&if_addr
->addr
.ip6_addr
,
396 (void *)&ai6
->sin6_addr
.s6_addr
,
397 sizeof if_addr
->addr
.ip6_addr
);
398 if_info
->addrs
= g_slist_append(if_info
->addrs
, if_addr
);
404 #ifdef HAVE_PCAP_FINDALLDEVS
406 * Get all IP address information for the given interface.
409 if_info_ip(if_info_t
*if_info
, pcap_if_t
*d
)
414 for (a
= d
->addresses
; a
!= NULL
; a
= a
->next
) {
416 if_info_add_address(if_info
, a
->addr
);
420 #ifdef HAVE_PCAP_REMOTE
422 get_interface_list_findalldevs_ex(const char *source
,
423 struct pcap_rmtauth
*auth
,
424 int *err
, char **err_str
)
427 pcap_if_t
*alldevs
, *dev
;
429 char errbuf
[PCAP_ERRBUF_SIZE
];
431 if (pcap_findalldevs_ex((char *)source
, auth
, &alldevs
, errbuf
) == -1) {
432 *err
= CANT_GET_INTERFACE_LIST
;
434 *err_str
= cant_get_if_list_error_message(errbuf
);
438 if (alldevs
== NULL
) {
440 * No interfaces found.
442 *err
= NO_INTERFACES_FOUND
;
448 for (dev
= alldevs
; dev
!= NULL
; dev
= dev
->next
) {
449 if_info
= if_info_new(dev
->name
, dev
->description
,
450 (dev
->flags
& PCAP_IF_LOOPBACK
) ? TRUE
: FALSE
);
451 il
= g_list_append(il
, if_info
);
452 if_info_ip(if_info
, dev
);
454 pcap_freealldevs(alldevs
);
461 get_interface_list_findalldevs(int *err
, char **err_str
)
464 pcap_if_t
*alldevs
, *dev
;
466 char errbuf
[PCAP_ERRBUF_SIZE
];
468 if (pcap_findalldevs(&alldevs
, errbuf
) == -1) {
469 *err
= CANT_GET_INTERFACE_LIST
;
471 *err_str
= cant_get_if_list_error_message(errbuf
);
475 if (alldevs
== NULL
) {
477 * No interfaces found.
479 *err
= NO_INTERFACES_FOUND
;
485 for (dev
= alldevs
; dev
!= NULL
; dev
= dev
->next
) {
486 if_info
= if_info_new(dev
->name
, dev
->description
,
487 (dev
->flags
& PCAP_IF_LOOPBACK
) ? TRUE
: FALSE
);
488 il
= g_list_append(il
, if_info
);
489 if_info_ip(if_info
, dev
);
491 pcap_freealldevs(alldevs
);
495 #endif /* HAVE_PCAP_FINDALLDEVS */
498 free_if_info_addr_cb(gpointer addr
, gpointer user_data _U_
)
504 free_if_cb(gpointer data
, gpointer user_data _U_
)
506 if_info_t
*if_info
= (if_info_t
*)data
;
508 g_free(if_info
->name
);
509 g_free(if_info
->friendly_name
);
510 g_free(if_info
->vendor_description
);
512 g_slist_foreach(if_info
->addrs
, free_if_info_addr_cb
, NULL
);
513 g_slist_free(if_info
->addrs
);
518 free_interface_list(GList
*if_list
)
520 g_list_foreach(if_list
, free_if_cb
, NULL
);
521 g_list_free(if_list
);
524 #if !defined(HAVE_PCAP_DATALINK_NAME_TO_VAL) || !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) || !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION)
527 const char *description
;
531 #define DLT_CHOICE(code, description) { #code, description, code }
532 #define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
534 static struct dlt_choice dlt_choices
[] = {
535 DLT_CHOICE(DLT_NULL
, "BSD loopback"),
536 DLT_CHOICE(DLT_EN10MB
, "Ethernet"),
537 DLT_CHOICE(DLT_IEEE802
, "Token ring"),
538 DLT_CHOICE(DLT_ARCNET
, "ARCNET"),
539 DLT_CHOICE(DLT_SLIP
, "SLIP"),
540 DLT_CHOICE(DLT_PPP
, "PPP"),
541 DLT_CHOICE(DLT_FDDI
, "FDDI"),
542 DLT_CHOICE(DLT_ATM_RFC1483
, "RFC 1483 IP-over-ATM"),
543 DLT_CHOICE(DLT_RAW
, "Raw IP"),
544 DLT_CHOICE(DLT_SLIP_BSDOS
, "BSD/OS SLIP"),
545 DLT_CHOICE(DLT_PPP_BSDOS
, "BSD/OS PPP"),
546 DLT_CHOICE(DLT_ATM_CLIP
, "Linux Classical IP-over-ATM"),
547 DLT_CHOICE(DLT_PPP_SERIAL
, "PPP over serial"),
548 DLT_CHOICE(DLT_PPP_ETHER
, "PPPoE"),
549 DLT_CHOICE(DLT_C_HDLC
, "Cisco HDLC"),
550 DLT_CHOICE(DLT_IEEE802_11
, "802.11"),
551 DLT_CHOICE(DLT_FRELAY
, "Frame Relay"),
552 DLT_CHOICE(DLT_LOOP
, "OpenBSD loopback"),
553 DLT_CHOICE(DLT_ENC
, "OpenBSD encapsulated IP"),
554 DLT_CHOICE(DLT_LINUX_SLL
, "Linux cooked"),
555 DLT_CHOICE(DLT_LTALK
, "Localtalk"),
556 DLT_CHOICE(DLT_PFLOG
, "OpenBSD pflog file"),
557 DLT_CHOICE(DLT_PRISM_HEADER
, "802.11 plus Prism header"),
558 DLT_CHOICE(DLT_IP_OVER_FC
, "RFC 2625 IP-over-Fibre Channel"),
559 DLT_CHOICE(DLT_SUNATM
, "Sun raw ATM"),
560 DLT_CHOICE(DLT_IEEE802_11_RADIO
, "802.11 plus BSD radio information header"),
561 DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394
, "Apple IP-over-IEEE 1394"),
562 DLT_CHOICE(DLT_ARCNET_LINUX
, "Linux ARCNET"),
563 DLT_CHOICE(DLT_LINUX_IRDA
, "Linux IrDA"),
564 DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS
, "802.11 plus AVS radio information header"),
568 #if !defined(HAVE_PCAP_DATALINK_NAME_TO_VAL)
570 pcap_datalink_name_to_val(const char *name
)
574 for (i
= 0; dlt_choices
[i
].name
!= NULL
; i
++) {
575 if (g_ascii_strcasecmp(dlt_choices
[i
].name
+ sizeof("DLT_") - 1,
577 return (dlt_choices
[i
].dlt
);
581 #endif /* defined(HAVE_PCAP_DATALINK_NAME_TO_VAL) */
583 #if !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME)
585 pcap_datalink_val_to_name(int dlt
)
589 for (i
= 0; dlt_choices
[i
].name
!= NULL
; i
++) {
590 if (dlt_choices
[i
].dlt
== dlt
)
591 return (dlt_choices
[i
].name
+ sizeof("DLT_") - 1);
595 #endif /* defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) */
597 #if !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION)
599 pcap_datalink_val_to_description(int dlt
)
603 for (i
= 0; dlt_choices
[i
].name
!= NULL
; i
++) {
604 if (dlt_choices
[i
].dlt
== dlt
)
605 return (dlt_choices
[i
].description
);
609 #endif /* defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION) */
611 #endif /* !defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) || !defined(HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION) */
614 free_linktype_cb(gpointer data
, gpointer user_data _U_
)
616 data_link_info_t
*linktype_info
= (data_link_info_t
*)data
;
618 g_free(linktype_info
->name
);
619 g_free(linktype_info
->description
);
623 free_if_capabilities(if_capabilities_t
*caps
)
625 g_list_foreach(caps
->data_link_types
, free_linktype_cb
, NULL
);
626 g_list_free(caps
->data_link_types
);
631 linktype_val_to_name(int dlt
)
633 return pcap_datalink_val_to_name(dlt
);
636 int linktype_name_to_val(const char *linktype
)
638 return pcap_datalink_name_to_val(linktype
);
641 #endif /* HAVE_LIBPCAP */