2 * Routines for network object lookup
4 * $Id: resolv.c,v 1.21 1999/11/22 06:03:46 gram Exp $
6 * Laurent Deniel <deniel@worldnet.fr>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #ifndef AVOID_DNS_TIMEOUT
38 #define AVOID_DNS_TIMEOUT
46 #ifdef HAVE_SYS_TYPES_H
47 # include <sys/types.h>
50 #ifdef HAVE_NETINET_IN_H
51 # include <netinet/in.h>
58 #include <arpa/inet.h>
62 #ifdef HAVE_SYS_SOCKET_H
63 #include <sys/socket.h>
66 #ifdef AVOID_DNS_TIMEOUT
70 #ifdef NEED_INET_V6DEFS_H
71 # include "inet_v6defs.h"
75 #include "packet-ipv6.h"
76 #include "packet-ipx.h"
80 #define MAXMANUFLEN 9 /* max vendor name length with ending '\0' */
81 #define HASHETHSIZE 1024
82 #define HASHHOSTSIZE 1024
83 #define HASHIPXNETSIZE 256
84 #define HASHMANUFSIZE 256
85 #define HASHPORTSIZE 256
87 /* hash table used for host and port lookup */
89 typedef struct hashname {
91 u_char name[MAXNAMELEN];
92 struct hashname *next;
95 /* hash table used for IPX network lookup */
97 typedef struct hashname hashipxnet_t;
99 /* hash tables used for ethernet and manufacturer lookup */
101 typedef struct hashmanuf {
103 char name[MAXMANUFLEN];
104 struct hashmanuf *next;
107 typedef struct hashether {
109 char name[MAXNAMELEN];
110 gboolean is_name_from_file;
111 struct hashether *next;
114 /* internal ethernet type */
116 typedef struct _ether
119 char name[MAXNAMELEN];
122 /* internal ipxnet type */
124 typedef struct _ipxnet
127 char name[MAXNAMELEN];
130 static hashname_t *host_table[HASHHOSTSIZE];
131 static hashname_t *udp_port_table[HASHPORTSIZE];
132 static hashname_t *tcp_port_table[HASHPORTSIZE];
133 static hashether_t *eth_table[HASHETHSIZE];
134 static hashmanuf_t *manuf_table[HASHMANUFSIZE];
135 static hashipxnet_t *ipxnet_table[HASHIPXNETSIZE];
137 static int eth_resolution_initialized = 0;
138 static int ipxnet_resolution_initialized = 0;
141 * Global variables (can be changed in GUI sections)
144 int g_resolving_actif = 1; /* routines are active by default */
146 gchar *g_ethers_path = EPATH_ETHERS;
147 gchar *g_pethers_path = NULL; /* "$HOME"/EPATH_PERSONAL_ETHERS */
148 gchar *g_ipxnets_path = EPATH_IPXNETS;
149 gchar *g_pipxnets_path = NULL; /* "$HOME"/EPATH_PERSONAL_IPXNETS */
150 gchar *g_manuf_path = EPATH_MANUF; /* may only be changed before the */
151 /* first resolving call */
154 * Local function definitions
157 static u_char *serv_name_lookup(u_int port, u_int proto)
162 char *serv_proto = NULL;
163 struct servent *servp;
168 table = udp_port_table;
172 table = tcp_port_table;
176 /* not yet implemented */
182 i = port & (HASHPORTSIZE - 1);
183 tp = table[ i & (HASHPORTSIZE - 1)];
186 tp = table[ i & (HASHPORTSIZE - 1)] =
187 (hashname_t *)g_malloc(sizeof(hashname_t));
190 if( tp->addr == port ) {
193 if (tp->next == NULL) {
194 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
202 /* fill in a new entry */
206 if ((servp = getservbyport(htons(port), serv_proto)) == NULL) {
208 sprintf(tp->name, "%d", port);
210 strncpy(tp->name, servp->s_name, MAXNAMELEN);
211 tp->name[MAXNAMELEN-1] = '\0';
216 } /* serv_name_lookup */
218 #ifdef AVOID_DNS_TIMEOUT
220 #define DNS_TIMEOUT 2 /* max sec per call */
222 jmp_buf hostname_env;
224 static void abort_network_query(int sig)
226 longjmp(hostname_env, 1);
228 #endif /* AVOID_DNS_TIMEOUT */
230 static u_char *host_name_lookup(u_int addr)
233 hashname_t * volatile tp;
234 hashname_t **table = host_table;
235 struct hostent *hostp;
237 tp = table[ addr & (HASHHOSTSIZE - 1)];
240 tp = table[ addr & (HASHHOSTSIZE - 1)] =
241 (hashname_t *)g_malloc(sizeof(hashname_t));
244 if( tp->addr == addr ) {
247 if (tp->next == NULL) {
248 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
256 /* fill in a new entry */
260 #ifdef AVOID_DNS_TIMEOUT
262 /* Quick hack to avoid DNS/YP timeout */
264 if (!setjmp(hostname_env)) {
265 signal(SIGALRM, abort_network_query);
268 hostp = gethostbyaddr((char *)&addr, 4, AF_INET);
269 #ifdef AVOID_DNS_TIMEOUT
273 strncpy(tp->name, hostp->h_name, MAXNAMELEN);
274 tp->name[MAXNAMELEN-1] = '\0';
277 #ifdef AVOID_DNS_TIMEOUT
281 /* unknown host or DNS timeout */
283 sprintf(tp->name, "%s", ip_to_str((guint8 *)&addr));
287 } /* host_name_lookup */
289 static u_char *host_name_lookup6(struct e_in6_addr *addr)
291 static u_char name[MAXNAMELEN];
293 struct hostent *hostp;
295 #ifdef AVOID_DNS_TIMEOUT
297 /* Quick hack to avoid DNS/YP timeout */
299 if (!setjmp(hostname_env)) {
300 signal(SIGALRM, abort_network_query);
302 #endif /* AVOID_DNS_TIMEOUT */
303 hostp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET6);
304 #ifdef AVOID_DNS_TIMEOUT
308 strncpy(name, hostp->h_name, MAXNAMELEN);
309 name[MAXNAMELEN-1] = '\0';
312 #ifdef AVOID_DNS_TIMEOUT
316 /* unknown host or DNS timeout */
318 sprintf(name, "%s", ip6_to_str(addr));
323 * Miscellaneous functions
326 static int fgetline(char **buf, int *size, FILE *fp)
338 if ((*buf = g_malloc(*size)) == NULL)
346 while ((c = getc(fp)) != EOF && c != '\n') {
347 if (len+1 >= *size) {
348 if ((*buf = g_realloc(*buf, *size += BUFSIZ)) == NULL)
354 if (len == 0 && c == EOF)
365 * Ethernet / manufacturer resolution
367 * The following functions implement ethernet address resolution and
368 * ethers files parsing (see ethers(4)).
370 * /etc/manuf has the same format as ethers(4) except that names are
371 * truncated to MAXMANUFLEN-1 characters and that an address contains
372 * only 3 bytes (instead of 6).
376 * I decide to not use the existing functions (see ethers(3) on some
377 * operating systems) for the following reasons:
378 * - performance gains (use of hash tables and some other enhancements),
379 * - use of two ethers files (system-wide and per user),
380 * - avoid the use of NIS maps,
381 * - lack of these functions on some systems.
383 * So the following functions do _not_ behave as the standard ones.
389 static int parse_ether_line(char *line, ether_t *eth, int six_bytes)
392 * See man ethers(4) for /etc/ethers file format
393 * (not available on all systems).
394 * We allow both ethernet address separators (':' and '-'),
395 * as well as Ethereal's '.' separator.
399 int a0, a1, a2, a3, a4, a5;
401 if ((cp = strchr(line, '#')))
404 if ((cp = strtok(line, " \t\n")) == NULL)
408 if (sscanf(cp, "%x:%x:%x:%x:%x:%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6) {
409 if (sscanf(cp, "%x-%x-%x-%x-%x-%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6) {
410 if (sscanf(cp, "%x.%x.%x.%x.%x.%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6)
415 if (sscanf(cp, "%x:%x:%x", &a0, &a1, &a2) != 3) {
416 if (sscanf(cp, "%x-%x-%x", &a0, &a1, &a2) != 3) {
417 if (sscanf(cp, "%x.%x.%x", &a0, &a1, &a2) != 3)
423 if ((cp = strtok(NULL, " \t\n")) == NULL)
439 strncpy(eth->name, cp, MAXNAMELEN);
440 eth->name[MAXNAMELEN-1] = '\0';
444 } /* parse_ether_line */
446 static FILE *eth_p = NULL;
448 static void set_ethent(char *path)
453 eth_p = fopen(path, "r");
456 static void end_ethent(void)
464 static ether_t *get_ethent(int six_bytes)
469 static char *buf = NULL;
474 while (fgetline(&buf, &size, eth_p) >= 0) {
475 if (parse_ether_line(buf, ð, six_bytes) == 0) {
484 static ether_t *get_ethbyname(u_char *name)
488 set_ethent(g_ethers_path);
490 while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
496 set_ethent(g_pethers_path);
498 while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
506 } /* get_ethbyname */
508 static ether_t *get_ethbyaddr(const u_char *addr)
513 set_ethent(g_ethers_path);
515 while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
521 set_ethent(g_pethers_path);
523 while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
531 } /* get_ethbyaddr */
533 static void add_manuf_name(u_char *addr, u_char *name)
537 hashmanuf_t **table = manuf_table;
539 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
542 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)] =
543 (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
546 if (tp->next == NULL) {
547 tp->next = (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
555 memcpy(tp->addr, addr, sizeof(tp->addr));
556 strncpy(tp->name, name, MAXMANUFLEN);
557 tp->name[MAXMANUFLEN-1] = '\0';
560 } /* add_manuf_name */
562 static hashmanuf_t *manuf_name_lookup(const u_char *addr)
566 hashmanuf_t **table = manuf_table;
568 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
571 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
579 } /* manuf_name_lookup */
581 static void initialize_ethers(void)
586 signal(SIGSEGV, SIG_IGN);
589 /* Set g_pethers_path here, but don't actually do anything
590 * with it. It's used in get_ethbyname() and get_ethbyaddr()
592 if (g_pethers_path == NULL) {
593 g_pethers_path = g_malloc(strlen(getenv("HOME")) +
594 strlen(EPATH_PERSONAL_ETHERS) + 2);
595 sprintf(g_pethers_path, "%s/%s",
596 (char *)getenv("HOME"), EPATH_PERSONAL_ETHERS);
599 /* manuf hash table initialization */
601 set_ethent(g_manuf_path);
603 while ((eth = get_ethent(0))) {
604 add_manuf_name(eth->addr, eth->name);
609 } /* initialize_ethers */
611 static hashether_t *add_eth_name(u_char *addr, u_char *name)
614 hashether_t **table = eth_table;
617 j = (addr[2] << 8) | addr[3];
618 i = (addr[4] << 8) | addr[5];
620 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
623 tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
624 (hashether_t *)g_malloc(sizeof(hashether_t));
627 if (tp->next == NULL) {
628 tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
636 memcpy(tp->addr, addr, sizeof(tp->addr));
637 strncpy(tp->name, name, MAXNAMELEN);
638 tp->name[MAXNAMELEN-1] = '\0';
645 static u_char *eth_name_lookup(const u_char *addr)
649 hashether_t **table = eth_table;
653 j = (addr[2] << 8) | addr[3];
654 i = (addr[4] << 8) | addr[5];
656 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
659 tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
660 (hashether_t *)g_malloc(sizeof(hashether_t));
663 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
666 if (tp->next == NULL) {
667 tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
675 /* fill in a new entry */
677 memcpy(tp->addr, addr, sizeof(tp->addr));
680 if ( (eth = get_ethbyaddr(addr)) == NULL) {
683 if ((manufp = manuf_name_lookup(addr)) == NULL)
684 sprintf(tp->name, "%s", ether_to_str((guint8 *)addr));
686 sprintf(tp->name, "%s_%02x:%02x:%02x",
687 manufp->name, addr[3], addr[4], addr[5]);
689 tp->is_name_from_file = FALSE;
692 strncpy(tp->name, eth->name, MAXNAMELEN);
693 tp->name[MAXNAMELEN-1] = '\0';
694 tp->is_name_from_file = TRUE;
699 } /* eth_name_lookup */
701 static u_char *eth_addr_lookup(u_char *name)
705 hashether_t **table = eth_table;
708 /* to be optimized (hash table from name to addr) */
709 for (i = 0; i < HASHETHSIZE; i++) {
712 if (strcmp(tp->name, name) == 0)
718 /* not in hash table : performs a file lookup */
720 if ((eth = get_ethbyname(name)) == NULL)
723 /* add new entry in hash table */
725 tp = add_eth_name(eth->addr, name);
729 } /* eth_addr_lookup */
733 static int parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
736 * We allow three address separators (':', '-', and '.'),
737 * as well as no separators
741 guint32 a, a0, a1, a2, a3;
742 gboolean found_single_number = FALSE;
744 if ((cp = strchr(line, '#')))
747 if ((cp = strtok(line, " \t\n")) == NULL)
750 /* Either fill a0,a1,a2,a3 and found_single_number is FALSE,
751 * fill a and found_single_number is TRUE,
754 if (sscanf(cp, "%x:%x:%x:%x", &a0, &a1, &a2, &a3) != 4) {
755 if (sscanf(cp, "%x-%x-%x-%x", &a0, &a1, &a2, &a3) != 4) {
756 if (sscanf(cp, "%x.%x.%x.%x", &a0, &a1, &a2, &a3) != 4) {
757 if (sscanf(cp, "%x", &a) == 1) {
758 found_single_number = TRUE;
767 if ((cp = strtok(NULL, " \t\n")) == NULL)
770 if (found_single_number) {
774 ipxnet->addr = (a0 << 24) | (a1 << 16) | (a2 << 8) | a3;
777 strncpy(ipxnet->name, cp, MAXNAMELEN);
778 ipxnet->name[MAXNAMELEN-1] = '\0';
782 } /* parse_ipxnets_line */
784 static FILE *ipxnet_p = NULL;
786 static void set_ipxnetent(char *path)
791 ipxnet_p = fopen(path, "r");
794 static void end_ipxnetent(void)
802 static ipxnet_t *get_ipxnetent(void)
805 static ipxnet_t ipxnet;
807 static char *buf = NULL;
809 if (ipxnet_p == NULL)
812 while (fgetline(&buf, &size, ipxnet_p) >= 0) {
813 if (parse_ipxnets_line(buf, &ipxnet) == 0) {
820 } /* get_ipxnetent */
822 static ipxnet_t *get_ipxnetbyname(u_char *name)
826 set_ipxnetent(g_ipxnets_path);
828 while ((ipxnet = get_ipxnetent()) && strncmp(name, ipxnet->name, MAXNAMELEN) != 0)
831 if (ipxnet == NULL) {
834 set_ipxnetent(g_pipxnets_path);
836 while ((ipxnet = get_ipxnetent()) && strncmp(name, ipxnet->name, MAXNAMELEN) != 0)
844 } /* get_ipxnetbyname */
846 static ipxnet_t *get_ipxnetbyaddr(guint32 addr)
851 set_ipxnetent(g_ipxnets_path);
853 while ((ipxnet = get_ipxnetent()) && (addr != ipxnet->addr) ) ;
855 if (ipxnet == NULL) {
858 set_ipxnetent(g_pipxnets_path);
860 while ((ipxnet = get_ipxnetent()) && (addr != ipxnet->addr) )
868 } /* get_ipxnetbyaddr */
870 static void initialize_ipxnets(void)
874 signal(SIGSEGV, SIG_IGN);
877 /* Set g_pipxnets_path here, but don't actually do anything
878 * with it. It's used in get_ipxnetbyname() and get_ipxnetbyaddr()
880 if (g_pipxnets_path == NULL) {
881 g_pipxnets_path = g_malloc(strlen(getenv("HOME")) +
882 strlen(EPATH_PERSONAL_IPXNETS) + 2);
883 sprintf(g_pipxnets_path, "%s/%s",
884 (char *)getenv("HOME"), EPATH_PERSONAL_IPXNETS);
887 } /* initialize_ipxnets */
889 static hashipxnet_t *add_ipxnet_name(u_int addr, u_char *name)
892 hashipxnet_t **table = ipxnet_table;
894 /* XXX - check goodness of hash function */
896 tp = table[ addr & (HASHIPXNETSIZE - 1)];
899 tp = table[ addr & (HASHIPXNETSIZE - 1)] =
900 (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
903 if (tp->next == NULL) {
904 tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
913 strncpy(tp->name, name, MAXNAMELEN);
914 tp->name[MAXNAMELEN-1] = '\0';
919 } /* add_ipxnet_name */
921 static u_char *ipxnet_name_lookup(const u_int addr)
924 hashipxnet_t **table = ipxnet_table;
927 tp = table[ addr & (HASHIPXNETSIZE - 1)];
930 tp = table[ addr & (HASHIPXNETSIZE - 1)] =
931 (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
934 if (tp->addr == addr) {
937 if (tp->next == NULL) {
938 tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
946 /* fill in a new entry */
951 if ( (ipxnet = get_ipxnetbyaddr(addr)) == NULL) {
953 sprintf(tp->name, "%X", addr);
956 strncpy(tp->name, ipxnet->name, MAXNAMELEN);
957 tp->name[MAXNAMELEN-1] = '\0';
962 } /* ipxnet_name_lookup */
964 static u_int ipxnet_addr_lookup(u_char *name, gboolean *success)
968 hashipxnet_t **table = ipxnet_table;
971 /* to be optimized (hash table from name to addr) */
972 for (i = 0; i < HASHIPXNETSIZE; i++) {
975 if (strcmp(tp->name, name) == 0)
981 /* not in hash table : performs a file lookup */
983 if ((ipxnet = get_ipxnetbyname(name)) == NULL) {
988 /* add new entry in hash table */
990 tp = add_ipxnet_name(ipxnet->addr, name);
995 } /* ipxnet_addr_lookup */
1002 extern u_char *get_hostname(u_int addr)
1004 if (!g_resolving_actif)
1005 return ip_to_str((guint8 *)&addr);
1007 return host_name_lookup(addr);
1010 extern gchar *get_hostname6(struct e_in6_addr *addr)
1013 if (!g_resolving_actif)
1014 return ip6_to_str(addr);
1015 if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MULTICAST(addr))
1016 return ip6_to_str(addr);
1018 return host_name_lookup6(addr);
1021 extern void add_host_name(u_int addr, u_char *name)
1025 hashname_t **table = host_table;
1027 tp = table[ addr & (HASHHOSTSIZE - 1)];
1030 tp = table[ addr & (HASHHOSTSIZE - 1)] =
1031 (hashname_t *)g_malloc(sizeof(hashname_t));
1034 if (tp->next == NULL) {
1035 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
1043 strncpy(tp->name, name, MAXNAMELEN);
1044 tp->name[MAXNAMELEN-1] = '\0';
1048 } /* add_host_name */
1050 extern u_char *get_udp_port(u_int port)
1052 static gchar str[3][MAXNAMELEN];
1055 if (!g_resolving_actif) {
1056 if (cur == &str[0][0]) {
1058 } else if (cur == &str[1][0]) {
1063 sprintf(cur, "%d", port);
1067 return serv_name_lookup(port, IPPROTO_UDP);
1069 } /* get_udp_port */
1071 extern u_char *get_tcp_port(u_int port)
1073 static gchar str[3][MAXNAMELEN];
1076 if (!g_resolving_actif) {
1077 if (cur == &str[0][0]) {
1079 } else if (cur == &str[1][0]) {
1084 sprintf(cur, "%d", port);
1088 return serv_name_lookup(port, IPPROTO_TCP);
1090 } /* get_tcp_port */
1092 extern u_char *get_ether_name(const u_char *addr)
1094 if (!g_resolving_actif)
1095 return ether_to_str((guint8 *)addr);
1097 if (!eth_resolution_initialized) {
1098 initialize_ethers();
1099 eth_resolution_initialized = 1;
1102 return eth_name_lookup(addr);
1104 } /* get_ether_name */
1106 /* Look for an ether name in the hash, and return it if found.
1107 * If it's not found, simply return NULL. We DO NOT make a new
1108 * hash entry for it with the hex digits turned into a string.
1110 u_char *get_ether_name_if_known(const u_char *addr)
1113 hashether_t **table = eth_table;
1116 /* Initialize ether structs if we're the first
1117 * ether-related function called */
1118 if (!g_resolving_actif)
1121 if (!eth_resolution_initialized) {
1122 initialize_ethers();
1123 eth_resolution_initialized = 1;
1126 j = (addr[2] << 8) | addr[3];
1127 i = (addr[4] << 8) | addr[5];
1129 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
1132 /* Hash key not found in table.
1133 * Force a lookup (and a hash entry) for addr, then call
1134 * myself. I plan on not getting into an infinite loop because
1135 * eth_name_lookup() is guaranteed to make a hashtable entry,
1136 * so when I call myself again, I can never get into this
1137 * block of code again. Knock on wood...
1139 (void) eth_name_lookup(addr);
1140 return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
1144 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
1145 if (tp->is_name_from_file) {
1146 /* A name was found, and its origin is an ethers file */
1150 /* A name was found, but it was created, not found in a file */
1154 if (tp->next == NULL) {
1155 /* Read my reason above for why I'm sure I can't get into an infinite loop */
1156 (void) eth_name_lookup(addr);
1157 return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
1162 g_assert_not_reached();
1167 extern u_char *get_ether_addr(u_char *name)
1170 /* force resolution (do not check g_resolving_actif) */
1172 if (!eth_resolution_initialized) {
1173 initialize_ethers();
1174 eth_resolution_initialized = 1;
1177 return eth_addr_lookup(name);
1179 } /* get_ether_addr */
1182 extern u_char *get_ipxnet_name(const guint32 addr)
1185 if (!g_resolving_actif) {
1186 return ipxnet_to_str_punct(addr, '\0');
1189 if (!ipxnet_resolution_initialized) {
1190 initialize_ipxnets();
1191 ipxnet_resolution_initialized = 1;
1194 return ipxnet_name_lookup(addr);
1196 } /* get_ipxnet_name */
1198 extern guint32 get_ipxnet_addr(u_char *name, gboolean *known)
1203 /* force resolution (do not check g_resolving_actif) */
1205 if (!ipxnet_resolution_initialized) {
1206 initialize_ipxnets();
1207 ipxnet_resolution_initialized = 1;
1210 addr = ipxnet_addr_lookup(name, &success);
1215 } /* get_ipxnet_addr */
1217 extern u_char *get_manuf_name(u_char *addr)
1219 static gchar str[3][MAXMANUFLEN];
1221 hashmanuf_t *manufp;
1223 if (g_resolving_actif && !eth_resolution_initialized) {
1224 initialize_ethers();
1225 eth_resolution_initialized = 1;
1228 if (!g_resolving_actif || ((manufp = manuf_name_lookup(addr)) == NULL)) {
1229 if (cur == &str[0][0]) {
1231 } else if (cur == &str[1][0]) {
1236 sprintf(cur, "%02x:%02x:%02x", addr[0], addr[1], addr[2]);
1240 return manufp->name;
1242 } /* get_manuf_name */
1246 /* Translate a string, assumed either to be a dotted-quad IP address or
1247 * a host name, to a numeric IP address. Return TRUE if we succeed and
1248 * set "*addrp" to that numeric IP address; return FALSE if we fail.
1249 * Used more in the dfilter parser rather than in packet dissectors */
1250 gboolean get_host_ipaddr(const char *host, guint32 *addrp)
1252 struct in_addr ipaddr;
1256 * don't change it to inet_pton(AF_INET), they are not 100% compatible.
1257 * inet_pton(AF_INET) does not support hexadecimal notation nor
1258 * less-than-4 octet notation.
1260 if (!inet_aton(host, &ipaddr)) {
1261 /* It's not a valid dotted-quad IP address; is it a valid
1263 hp = gethostbyname(host);
1268 /* XXX - is "hp->h_length" the size of a
1269 * "struct in_addr"? It should be. */
1270 memcpy(&ipaddr, hp->h_addr, hp->h_length);
1274 *addrp = ntohl(ipaddr.s_addr);
1279 * Translate IPv6 numeric address or FQDN hostname, into binary IPv6 address.
1280 * Return TRUE if we succeed and set "*addrp" to that numeric IP address;
1281 * return FALSE if we fail.
1283 gboolean get_host_ipaddr6(const char *host, struct e_in6_addr *addrp)
1287 if (inet_pton(AF_INET6, host, addrp) == 1)
1291 #ifdef HAVE_GETHOSTBYNAME2
1292 hp = gethostbyname2(host, AF_INET6);
1296 if (hp != NULL && hp->h_length == sizeof(struct e_in6_addr)) {
1297 memcpy(addrp, hp->h_addr, hp->h_length);