]>
The Tcpdump Group git mirrors - tcpdump/blob - win32/src/ether_ntohost.c
0217b195559a2e4c8a6b8323b870a8135183fd03
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that: (1) source code distributions
4 * retain the above copyright notice and this paragraph in its entirety, (2)
5 * distributions including binary code include the above copyright notice and
6 * this paragraph in its entirety in the documentation or other materials
7 * provided with the distribution, and (3) all advertising materials mentioning
8 * features or use of this software display the following acknowledgement:
9 * ``This product includes software developed by the University of California,
10 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
11 * the University nor the names of its contributors may be used to endorse
12 * or promote products derived from this software without specific prior
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 * tcpdump/Win32 functions for reading and parsing system's Ethernet
20 * '%SystemRoot%/drivers/etc/ethers' (Win-NT+)
21 * or '%Windir%/etc/ethers' (Win-9x/ME)
23 * G. Vanem <gvanem@yahoo.no> 2012.
30 #include <netdissect-stdinc.h>
33 #include "interface.h"
34 #include "addrtoname.h"
36 typedef struct ether_addr
{
37 unsigned char octet
[ETHER_ADDR_LEN
];
40 typedef struct ether_entry
{
41 ether_address eth_addr
; /* MAC address */
42 char *name
; /* name of MAC-address */
43 struct ether_entry
*next
;
46 static struct ether_entry
*eth0
= NULL
;
49 * The reason to avoid using 'pcap_next_etherent()' in addrtoname.c
51 * 1) wpcap.dll and 'pcap_next_etherent()' could have been built in
52 * debug-mode (-MDd) or release-mode (-MD) and tcpdump in
54 * 2) If this is built by MSVC, wpcap.dll could have been built by
55 * MingW. It has no debug-model.
56 * 3) It may not have been exported from wpcap.dll (present in wpcap.def).
58 * So we shoe-horn the building of tcpdump with '-DUSE_ETHER_NTOHOST' to
59 * make 'init_etherarray()' call the below 'ether_ntohost()' instead.
61 #if !defined(USE_ETHER_NTOHOST)
62 #error "'-DUSE_ETHER_NTOHOST' must be set"
66 * Return TRUE if running under Win-95/98/ME.
68 static BOOL
is_win9x (void)
71 DWORD os_ver
= GetVersion();
72 DWORD major_ver
= LOBYTE (LOWORD(os_ver
));
74 return (os_ver
>= 0x80000000 && major_ver
>= 4);
78 * Return path to "%SystemRoot%/drivers/etc/<file>" (Win-NT+)
79 * or to "%Windir%/etc/<file>" (Win-9x/ME)
81 const char *etc_path (const char *file
)
83 BOOL win9x
= is_win9x();
84 const char *env
= win9x
? getenv("WinDir") : getenv("SystemRoot");
85 static char path
[MAX_PATH
];
91 snprintf (path
, sizeof(path
), "%s\\etc\\%s", env
, file
);
93 snprintf (path
, sizeof(path
), "%s\\system32\\drivers\\etc\\%s", env
, file
);
99 * Parse a string-buf containing an MAC address and name.
100 * Accepts MAC addresses on both "xx:xx:xx.." and "xx-xx-xx.." forms.
102 * We could have used pcap_ether_aton(), but problem 3) above could apply.
103 * or we could have cut & pasted 'pcap_next_etherent(FILE *fp)' below.
105 #define MIN_LEN sizeof("0:0:0:0:0:0 X")
108 int parse_ether_buf (const char *buf
, char **result
, struct ether_addr
*e
)
112 char *str
= (char*)buf
;
113 unsigned eth
[sizeof(*e
)];
116 /* Find first non-blank in 'buf' */
117 while (str
[0] && str
[1] && isspace((int)str
[0]))
120 if (*str
== '#' || *str
== ';' || *str
== '\n' || strlen(str
) < MIN_LEN
)
124 fmt
= "%02x:%02x:%02x:%02x:%02x:%02x";
126 fmt
= "%02x-%02x-%02x-%02x-%02x-%02x";
128 if (sscanf(str
, fmt
, ð
[0], ð
[1], ð
[2], ð
[3], ð
[4], ð
[5]) != ETHER_ADDR_LEN
)
131 str
= strtok (str
, " \t");
132 name
= strtok (NULL
, " #\t\n");
134 if (!str
|| !name
|| strlen(name
) < 1)
139 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++)
140 e
->octet
[i
] = eth
[i
];
145 static void free_ethers (void)
147 struct ether_entry
*e
, *next
;
149 for (e
= eth0
; e
; e
= next
) {
157 static int init_ethers (void)
160 FILE *fp
= fopen (etc_path("ethers"), "r");
165 while (fgets(buf
,sizeof(buf
),fp
))
167 struct ether_entry
*e
;
171 if (!parse_ether_buf(buf
,&name
,ð
))
174 e
= calloc (sizeof(*e
), 1);
178 memcpy(&e
->eth_addr
, ð
, ETHER_ADDR_LEN
);
179 e
->name
= strdup(name
);
194 * Map an ethernet address 'e' to a 'name'.
195 * Returns 0 on success.
197 * This function is called at startup by init_etherarray() and then
198 * by etheraddr_string() as needed. To avoid doing an expensive fopen()
199 * on each call, the contents of 'etc_path("ethers")' is cached here in
200 * a linked-list 'eth0'.
202 int ether_ntohost (char *name
, struct ether_addr
*e
)
204 const struct ether_entry
*cache
;
212 for (cache
= eth0
; cache
; cache
= cache
->next
)
213 if (!memcmp(&e
->octet
, &cache
->eth_addr
, ETHER_ADDR_LEN
)) {
214 strcpy (name
,cache
->name
);