2 * Routines for network object lookup
4 * $Id: resolv.c,v 1.23 2000/01/29 16:41:14 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 #ifdef HAVE_ARPA_INET_H
59 #include <arpa/inet.h>
64 #ifdef HAVE_SYS_SOCKET_H
65 #include <sys/socket.h>
68 #ifdef AVOID_DNS_TIMEOUT
72 #ifdef NEED_INET_V6DEFS_H
73 # include "inet_v6defs.h"
77 #include "packet-ipv6.h"
78 #include "packet-ipx.h"
83 #define MAXMANUFLEN 9 /* max vendor name length with ending '\0' */
84 #define HASHETHSIZE 1024
85 #define HASHHOSTSIZE 1024
86 #define HASHIPXNETSIZE 256
87 #define HASHMANUFSIZE 256
88 #define HASHPORTSIZE 256
90 /* hash table used for host and port lookup */
92 typedef struct hashname {
94 u_char name[MAXNAMELEN];
95 struct hashname *next;
98 /* hash table used for IPX network lookup */
100 typedef struct hashname hashipxnet_t;
102 /* hash tables used for ethernet and manufacturer lookup */
104 typedef struct hashmanuf {
106 char name[MAXMANUFLEN];
107 struct hashmanuf *next;
110 typedef struct hashether {
112 char name[MAXNAMELEN];
113 gboolean is_name_from_file;
114 struct hashether *next;
117 /* internal ethernet type */
119 typedef struct _ether
122 char name[MAXNAMELEN];
125 /* internal ipxnet type */
127 typedef struct _ipxnet
130 char name[MAXNAMELEN];
133 static hashname_t *host_table[HASHHOSTSIZE];
134 static hashname_t *udp_port_table[HASHPORTSIZE];
135 static hashname_t *tcp_port_table[HASHPORTSIZE];
136 static hashether_t *eth_table[HASHETHSIZE];
137 static hashmanuf_t *manuf_table[HASHMANUFSIZE];
138 static hashipxnet_t *ipxnet_table[HASHIPXNETSIZE];
140 static int eth_resolution_initialized = 0;
141 static int ipxnet_resolution_initialized = 0;
144 * Global variables (can be changed in GUI sections)
147 int g_resolving_actif = 1; /* routines are active by default */
149 gchar *g_ethers_path = EPATH_ETHERS;
150 gchar *g_pethers_path = NULL; /* "$HOME"/EPATH_PERSONAL_ETHERS */
151 gchar *g_ipxnets_path = EPATH_IPXNETS;
152 gchar *g_pipxnets_path = NULL; /* "$HOME"/EPATH_PERSONAL_IPXNETS */
153 gchar *g_manuf_path = EPATH_MANUF; /* may only be changed before the */
154 /* first resolving call */
157 * Local function definitions
160 static u_char *serv_name_lookup(u_int port, u_int proto)
165 char *serv_proto = NULL;
166 struct servent *servp;
171 table = udp_port_table;
175 table = tcp_port_table;
179 /* not yet implemented */
185 i = port & (HASHPORTSIZE - 1);
186 tp = table[ i & (HASHPORTSIZE - 1)];
189 tp = table[ i & (HASHPORTSIZE - 1)] =
190 (hashname_t *)g_malloc(sizeof(hashname_t));
193 if( tp->addr == port ) {
196 if (tp->next == NULL) {
197 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
205 /* fill in a new entry */
209 if ((servp = getservbyport(htons(port), serv_proto)) == NULL) {
211 sprintf(tp->name, "%d", port);
213 strncpy(tp->name, servp->s_name, MAXNAMELEN);
214 tp->name[MAXNAMELEN-1] = '\0';
219 } /* serv_name_lookup */
221 #ifdef AVOID_DNS_TIMEOUT
223 #define DNS_TIMEOUT 2 /* max sec per call */
225 jmp_buf hostname_env;
227 static void abort_network_query(int sig)
229 longjmp(hostname_env, 1);
231 #endif /* AVOID_DNS_TIMEOUT */
233 static u_char *host_name_lookup(u_int addr)
236 hashname_t * volatile tp;
237 hashname_t **table = host_table;
238 struct hostent *hostp;
240 tp = table[ addr & (HASHHOSTSIZE - 1)];
243 tp = table[ addr & (HASHHOSTSIZE - 1)] =
244 (hashname_t *)g_malloc(sizeof(hashname_t));
247 if( tp->addr == addr ) {
250 if (tp->next == NULL) {
251 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
259 /* fill in a new entry */
263 #ifdef AVOID_DNS_TIMEOUT
265 /* Quick hack to avoid DNS/YP timeout */
267 if (!setjmp(hostname_env)) {
268 signal(SIGALRM, abort_network_query);
271 hostp = gethostbyaddr((char *)&addr, 4, AF_INET);
272 #ifdef AVOID_DNS_TIMEOUT
276 strncpy(tp->name, hostp->h_name, MAXNAMELEN);
277 tp->name[MAXNAMELEN-1] = '\0';
280 #ifdef AVOID_DNS_TIMEOUT
284 /* unknown host or DNS timeout */
286 sprintf(tp->name, "%s", ip_to_str((guint8 *)&addr));
290 } /* host_name_lookup */
292 static u_char *host_name_lookup6(struct e_in6_addr *addr)
294 static u_char name[MAXNAMELEN];
296 struct hostent *hostp;
298 #ifdef AVOID_DNS_TIMEOUT
300 /* Quick hack to avoid DNS/YP timeout */
302 if (!setjmp(hostname_env)) {
303 signal(SIGALRM, abort_network_query);
305 #endif /* AVOID_DNS_TIMEOUT */
306 hostp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET6);
307 #ifdef AVOID_DNS_TIMEOUT
311 strncpy(name, hostp->h_name, MAXNAMELEN);
312 name[MAXNAMELEN-1] = '\0';
315 #ifdef AVOID_DNS_TIMEOUT
319 /* unknown host or DNS timeout */
321 sprintf(name, "%s", ip6_to_str(addr));
326 * Miscellaneous functions
329 static int fgetline(char **buf, int *size, FILE *fp)
341 if ((*buf = g_malloc(*size)) == NULL)
349 while ((c = getc(fp)) != EOF && c != '\n') {
350 if (len+1 >= *size) {
351 if ((*buf = g_realloc(*buf, *size += BUFSIZ)) == NULL)
357 if (len == 0 && c == EOF)
368 * Ethernet / manufacturer resolution
370 * The following functions implement ethernet address resolution and
371 * ethers files parsing (see ethers(4)).
373 * /etc/manuf has the same format as ethers(4) except that names are
374 * truncated to MAXMANUFLEN-1 characters and that an address contains
375 * only 3 bytes (instead of 6).
379 * I decide to not use the existing functions (see ethers(3) on some
380 * operating systems) for the following reasons:
381 * - performance gains (use of hash tables and some other enhancements),
382 * - use of two ethers files (system-wide and per user),
383 * - avoid the use of NIS maps,
384 * - lack of these functions on some systems.
386 * So the following functions do _not_ behave as the standard ones.
392 static int parse_ether_line(char *line, ether_t *eth, int six_bytes)
395 * See man ethers(4) for /etc/ethers file format
396 * (not available on all systems).
397 * We allow both ethernet address separators (':' and '-'),
398 * as well as Ethereal's '.' separator.
402 int a0, a1, a2, a3, a4, a5;
404 if ((cp = strchr(line, '#')))
407 if ((cp = strtok(line, " \t\n")) == NULL)
411 if (sscanf(cp, "%x:%x:%x:%x:%x:%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6) {
412 if (sscanf(cp, "%x-%x-%x-%x-%x-%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6) {
413 if (sscanf(cp, "%x.%x.%x.%x.%x.%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6)
418 if (sscanf(cp, "%x:%x:%x", &a0, &a1, &a2) != 3) {
419 if (sscanf(cp, "%x-%x-%x", &a0, &a1, &a2) != 3) {
420 if (sscanf(cp, "%x.%x.%x", &a0, &a1, &a2) != 3)
426 if ((cp = strtok(NULL, " \t\n")) == NULL)
442 strncpy(eth->name, cp, MAXNAMELEN);
443 eth->name[MAXNAMELEN-1] = '\0';
447 } /* parse_ether_line */
449 static FILE *eth_p = NULL;
451 static void set_ethent(char *path)
456 eth_p = fopen(path, "r");
459 static void end_ethent(void)
467 static ether_t *get_ethent(int six_bytes)
472 static char *buf = NULL;
477 while (fgetline(&buf, &size, eth_p) >= 0) {
478 if (parse_ether_line(buf, ð, six_bytes) == 0) {
487 static ether_t *get_ethbyname(u_char *name)
491 set_ethent(g_ethers_path);
493 while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
499 set_ethent(g_pethers_path);
501 while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
509 } /* get_ethbyname */
511 static ether_t *get_ethbyaddr(const u_char *addr)
516 set_ethent(g_ethers_path);
518 while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
524 set_ethent(g_pethers_path);
526 while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
534 } /* get_ethbyaddr */
536 static void add_manuf_name(u_char *addr, u_char *name)
540 hashmanuf_t **table = manuf_table;
542 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
545 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)] =
546 (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
549 if (tp->next == NULL) {
550 tp->next = (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
558 memcpy(tp->addr, addr, sizeof(tp->addr));
559 strncpy(tp->name, name, MAXMANUFLEN);
560 tp->name[MAXMANUFLEN-1] = '\0';
563 } /* add_manuf_name */
565 static hashmanuf_t *manuf_name_lookup(const u_char *addr)
569 hashmanuf_t **table = manuf_table;
571 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
574 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
582 } /* manuf_name_lookup */
584 static void initialize_ethers(void)
589 signal(SIGSEGV, SIG_IGN);
592 /* Set g_pethers_path here, but don't actually do anything
593 * with it. It's used in get_ethbyname() and get_ethbyaddr()
595 if (g_pethers_path == NULL) {
596 g_pethers_path = g_malloc(strlen(get_home_dir()) +
597 strlen(EPATH_PERSONAL_ETHERS) + 2);
598 sprintf(g_pethers_path, "%s/%s",
599 get_home_dir(), EPATH_PERSONAL_ETHERS);
602 /* manuf hash table initialization */
604 set_ethent(g_manuf_path);
606 while ((eth = get_ethent(0))) {
607 add_manuf_name(eth->addr, eth->name);
612 } /* initialize_ethers */
614 static hashether_t *add_eth_name(u_char *addr, u_char *name)
617 hashether_t **table = eth_table;
620 j = (addr[2] << 8) | addr[3];
621 i = (addr[4] << 8) | addr[5];
623 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
626 tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
627 (hashether_t *)g_malloc(sizeof(hashether_t));
630 if (tp->next == NULL) {
631 tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
639 memcpy(tp->addr, addr, sizeof(tp->addr));
640 strncpy(tp->name, name, MAXNAMELEN);
641 tp->name[MAXNAMELEN-1] = '\0';
648 static u_char *eth_name_lookup(const u_char *addr)
652 hashether_t **table = eth_table;
656 j = (addr[2] << 8) | addr[3];
657 i = (addr[4] << 8) | addr[5];
659 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
662 tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
663 (hashether_t *)g_malloc(sizeof(hashether_t));
666 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
669 if (tp->next == NULL) {
670 tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
678 /* fill in a new entry */
680 memcpy(tp->addr, addr, sizeof(tp->addr));
683 if ( (eth = get_ethbyaddr(addr)) == NULL) {
686 if ((manufp = manuf_name_lookup(addr)) == NULL)
687 sprintf(tp->name, "%s", ether_to_str((guint8 *)addr));
689 sprintf(tp->name, "%s_%02x:%02x:%02x",
690 manufp->name, addr[3], addr[4], addr[5]);
692 tp->is_name_from_file = FALSE;
695 strncpy(tp->name, eth->name, MAXNAMELEN);
696 tp->name[MAXNAMELEN-1] = '\0';
697 tp->is_name_from_file = TRUE;
702 } /* eth_name_lookup */
704 static u_char *eth_addr_lookup(u_char *name)
708 hashether_t **table = eth_table;
711 /* to be optimized (hash table from name to addr) */
712 for (i = 0; i < HASHETHSIZE; i++) {
715 if (strcmp(tp->name, name) == 0)
721 /* not in hash table : performs a file lookup */
723 if ((eth = get_ethbyname(name)) == NULL)
726 /* add new entry in hash table */
728 tp = add_eth_name(eth->addr, name);
732 } /* eth_addr_lookup */
736 static int parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
739 * We allow three address separators (':', '-', and '.'),
740 * as well as no separators
744 guint32 a, a0, a1, a2, a3;
745 gboolean found_single_number = FALSE;
747 if ((cp = strchr(line, '#')))
750 if ((cp = strtok(line, " \t\n")) == NULL)
753 /* Either fill a0,a1,a2,a3 and found_single_number is FALSE,
754 * fill a and found_single_number is TRUE,
757 if (sscanf(cp, "%x:%x:%x:%x", &a0, &a1, &a2, &a3) != 4) {
758 if (sscanf(cp, "%x-%x-%x-%x", &a0, &a1, &a2, &a3) != 4) {
759 if (sscanf(cp, "%x.%x.%x.%x", &a0, &a1, &a2, &a3) != 4) {
760 if (sscanf(cp, "%x", &a) == 1) {
761 found_single_number = TRUE;
770 if ((cp = strtok(NULL, " \t\n")) == NULL)
773 if (found_single_number) {
777 ipxnet->addr = (a0 << 24) | (a1 << 16) | (a2 << 8) | a3;
780 strncpy(ipxnet->name, cp, MAXNAMELEN);
781 ipxnet->name[MAXNAMELEN-1] = '\0';
785 } /* parse_ipxnets_line */
787 static FILE *ipxnet_p = NULL;
789 static void set_ipxnetent(char *path)
794 ipxnet_p = fopen(path, "r");
797 static void end_ipxnetent(void)
805 static ipxnet_t *get_ipxnetent(void)
808 static ipxnet_t ipxnet;
810 static char *buf = NULL;
812 if (ipxnet_p == NULL)
815 while (fgetline(&buf, &size, ipxnet_p) >= 0) {
816 if (parse_ipxnets_line(buf, &ipxnet) == 0) {
823 } /* get_ipxnetent */
825 static ipxnet_t *get_ipxnetbyname(u_char *name)
829 set_ipxnetent(g_ipxnets_path);
831 while ((ipxnet = get_ipxnetent()) && strncmp(name, ipxnet->name, MAXNAMELEN) != 0)
834 if (ipxnet == NULL) {
837 set_ipxnetent(g_pipxnets_path);
839 while ((ipxnet = get_ipxnetent()) && strncmp(name, ipxnet->name, MAXNAMELEN) != 0)
847 } /* get_ipxnetbyname */
849 static ipxnet_t *get_ipxnetbyaddr(guint32 addr)
854 set_ipxnetent(g_ipxnets_path);
856 while ((ipxnet = get_ipxnetent()) && (addr != ipxnet->addr) ) ;
858 if (ipxnet == NULL) {
861 set_ipxnetent(g_pipxnets_path);
863 while ((ipxnet = get_ipxnetent()) && (addr != ipxnet->addr) )
871 } /* get_ipxnetbyaddr */
873 static void initialize_ipxnets(void)
877 signal(SIGSEGV, SIG_IGN);
880 /* Set g_pipxnets_path here, but don't actually do anything
881 * with it. It's used in get_ipxnetbyname() and get_ipxnetbyaddr()
883 if (g_pipxnets_path == NULL) {
884 g_pipxnets_path = g_malloc(strlen(get_home_dir()) +
885 strlen(EPATH_PERSONAL_IPXNETS) + 2);
886 sprintf(g_pipxnets_path, "%s/%s",
887 get_home_dir(), EPATH_PERSONAL_IPXNETS);
890 } /* initialize_ipxnets */
892 static hashipxnet_t *add_ipxnet_name(u_int addr, u_char *name)
895 hashipxnet_t **table = ipxnet_table;
897 /* XXX - check goodness of hash function */
899 tp = table[ addr & (HASHIPXNETSIZE - 1)];
902 tp = table[ addr & (HASHIPXNETSIZE - 1)] =
903 (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
906 if (tp->next == NULL) {
907 tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
916 strncpy(tp->name, name, MAXNAMELEN);
917 tp->name[MAXNAMELEN-1] = '\0';
922 } /* add_ipxnet_name */
924 static u_char *ipxnet_name_lookup(const u_int addr)
927 hashipxnet_t **table = ipxnet_table;
930 tp = table[ addr & (HASHIPXNETSIZE - 1)];
933 tp = table[ addr & (HASHIPXNETSIZE - 1)] =
934 (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
937 if (tp->addr == addr) {
940 if (tp->next == NULL) {
941 tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
949 /* fill in a new entry */
954 if ( (ipxnet = get_ipxnetbyaddr(addr)) == NULL) {
956 sprintf(tp->name, "%X", addr);
959 strncpy(tp->name, ipxnet->name, MAXNAMELEN);
960 tp->name[MAXNAMELEN-1] = '\0';
965 } /* ipxnet_name_lookup */
967 static u_int ipxnet_addr_lookup(u_char *name, gboolean *success)
971 hashipxnet_t **table = ipxnet_table;
974 /* to be optimized (hash table from name to addr) */
975 for (i = 0; i < HASHIPXNETSIZE; i++) {
978 if (strcmp(tp->name, name) == 0)
984 /* not in hash table : performs a file lookup */
986 if ((ipxnet = get_ipxnetbyname(name)) == NULL) {
991 /* add new entry in hash table */
993 tp = add_ipxnet_name(ipxnet->addr, name);
998 } /* ipxnet_addr_lookup */
1002 * External Functions
1005 extern u_char *get_hostname(u_int addr)
1007 if (!g_resolving_actif)
1008 return ip_to_str((guint8 *)&addr);
1010 return host_name_lookup(addr);
1013 extern gchar *get_hostname6(struct e_in6_addr *addr)
1016 if (!g_resolving_actif)
1017 return ip6_to_str(addr);
1018 if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MULTICAST(addr))
1019 return ip6_to_str(addr);
1021 return host_name_lookup6(addr);
1024 extern void add_host_name(u_int addr, u_char *name)
1028 hashname_t **table = host_table;
1030 tp = table[ addr & (HASHHOSTSIZE - 1)];
1033 tp = table[ addr & (HASHHOSTSIZE - 1)] =
1034 (hashname_t *)g_malloc(sizeof(hashname_t));
1037 if (tp->next == NULL) {
1038 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
1046 strncpy(tp->name, name, MAXNAMELEN);
1047 tp->name[MAXNAMELEN-1] = '\0';
1051 } /* add_host_name */
1053 extern u_char *get_udp_port(u_int port)
1055 static gchar str[3][MAXNAMELEN];
1058 if (!g_resolving_actif) {
1059 if (cur == &str[0][0]) {
1061 } else if (cur == &str[1][0]) {
1066 sprintf(cur, "%d", port);
1070 return serv_name_lookup(port, IPPROTO_UDP);
1072 } /* get_udp_port */
1074 extern u_char *get_tcp_port(u_int port)
1076 static gchar str[3][MAXNAMELEN];
1079 if (!g_resolving_actif) {
1080 if (cur == &str[0][0]) {
1082 } else if (cur == &str[1][0]) {
1087 sprintf(cur, "%d", port);
1091 return serv_name_lookup(port, IPPROTO_TCP);
1093 } /* get_tcp_port */
1095 extern u_char *get_ether_name(const u_char *addr)
1097 if (!g_resolving_actif)
1098 return ether_to_str((guint8 *)addr);
1100 if (!eth_resolution_initialized) {
1101 initialize_ethers();
1102 eth_resolution_initialized = 1;
1105 return eth_name_lookup(addr);
1107 } /* get_ether_name */
1109 /* Look for an ether name in the hash, and return it if found.
1110 * If it's not found, simply return NULL. We DO NOT make a new
1111 * hash entry for it with the hex digits turned into a string.
1113 u_char *get_ether_name_if_known(const u_char *addr)
1116 hashether_t **table = eth_table;
1119 /* Initialize ether structs if we're the first
1120 * ether-related function called */
1121 if (!g_resolving_actif)
1124 if (!eth_resolution_initialized) {
1125 initialize_ethers();
1126 eth_resolution_initialized = 1;
1129 j = (addr[2] << 8) | addr[3];
1130 i = (addr[4] << 8) | addr[5];
1132 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
1135 /* Hash key not found in table.
1136 * Force a lookup (and a hash entry) for addr, then call
1137 * myself. I plan on not getting into an infinite loop because
1138 * eth_name_lookup() is guaranteed to make a hashtable entry,
1139 * so when I call myself again, I can never get into this
1140 * block of code again. Knock on wood...
1142 (void) eth_name_lookup(addr);
1143 return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
1147 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
1148 if (tp->is_name_from_file) {
1149 /* A name was found, and its origin is an ethers file */
1153 /* A name was found, but it was created, not found in a file */
1157 if (tp->next == NULL) {
1158 /* Read my reason above for why I'm sure I can't get into an infinite loop */
1159 (void) eth_name_lookup(addr);
1160 return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
1165 g_assert_not_reached();
1170 extern u_char *get_ether_addr(u_char *name)
1173 /* force resolution (do not check g_resolving_actif) */
1175 if (!eth_resolution_initialized) {
1176 initialize_ethers();
1177 eth_resolution_initialized = 1;
1180 return eth_addr_lookup(name);
1182 } /* get_ether_addr */
1185 extern u_char *get_ipxnet_name(const guint32 addr)
1188 if (!g_resolving_actif) {
1189 return ipxnet_to_str_punct(addr, '\0');
1192 if (!ipxnet_resolution_initialized) {
1193 initialize_ipxnets();
1194 ipxnet_resolution_initialized = 1;
1197 return ipxnet_name_lookup(addr);
1199 } /* get_ipxnet_name */
1201 extern guint32 get_ipxnet_addr(u_char *name, gboolean *known)
1206 /* force resolution (do not check g_resolving_actif) */
1208 if (!ipxnet_resolution_initialized) {
1209 initialize_ipxnets();
1210 ipxnet_resolution_initialized = 1;
1213 addr = ipxnet_addr_lookup(name, &success);
1218 } /* get_ipxnet_addr */
1220 extern u_char *get_manuf_name(u_char *addr)
1222 static gchar str[3][MAXMANUFLEN];
1224 hashmanuf_t *manufp;
1226 if (g_resolving_actif && !eth_resolution_initialized) {
1227 initialize_ethers();
1228 eth_resolution_initialized = 1;
1231 if (!g_resolving_actif || ((manufp = manuf_name_lookup(addr)) == NULL)) {
1232 if (cur == &str[0][0]) {
1234 } else if (cur == &str[1][0]) {
1239 sprintf(cur, "%02x:%02x:%02x", addr[0], addr[1], addr[2]);
1243 return manufp->name;
1245 } /* get_manuf_name */
1249 /* Translate a string, assumed either to be a dotted-quad IP address or
1250 * a host name, to a numeric IP address. Return TRUE if we succeed and
1251 * set "*addrp" to that numeric IP address; return FALSE if we fail.
1252 * Used more in the dfilter parser rather than in packet dissectors */
1253 gboolean get_host_ipaddr(const char *host, guint32 *addrp)
1255 struct in_addr ipaddr;
1259 * don't change it to inet_pton(AF_INET), they are not 100% compatible.
1260 * inet_pton(AF_INET) does not support hexadecimal notation nor
1261 * less-than-4 octet notation.
1263 if (!inet_aton(host, &ipaddr)) {
1264 /* It's not a valid dotted-quad IP address; is it a valid
1266 hp = gethostbyname(host);
1271 /* XXX - is "hp->h_length" the size of a
1272 * "struct in_addr"? It should be. */
1273 memcpy(&ipaddr, hp->h_addr, hp->h_length);
1277 *addrp = ntohl(ipaddr.s_addr);
1282 * Translate IPv6 numeric address or FQDN hostname, into binary IPv6 address.
1283 * Return TRUE if we succeed and set "*addrp" to that numeric IP address;
1284 * return FALSE if we fail.
1286 gboolean get_host_ipaddr6(const char *host, struct e_in6_addr *addrp)
1290 if (inet_pton(AF_INET6, host, addrp) == 1)
1294 #ifdef HAVE_GETHOSTBYNAME2
1295 hp = gethostbyname2(host, AF_INET6);
1299 if (hp != NULL && hp->h_length == sizeof(struct e_in6_addr)) {
1300 memcpy(addrp, hp->h_addr, hp->h_length);