2 * Routines for network object lookup
4 * $Id: resolv.c,v 1.22 2000/01/10 17:32:52 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"
82 #define MAXMANUFLEN 9 /* max vendor name length with ending '\0' */
83 #define HASHETHSIZE 1024
84 #define HASHHOSTSIZE 1024
85 #define HASHIPXNETSIZE 256
86 #define HASHMANUFSIZE 256
87 #define HASHPORTSIZE 256
89 /* hash table used for host and port lookup */
91 typedef struct hashname {
93 u_char name[MAXNAMELEN];
94 struct hashname *next;
97 /* hash table used for IPX network lookup */
99 typedef struct hashname hashipxnet_t;
101 /* hash tables used for ethernet and manufacturer lookup */
103 typedef struct hashmanuf {
105 char name[MAXMANUFLEN];
106 struct hashmanuf *next;
109 typedef struct hashether {
111 char name[MAXNAMELEN];
112 gboolean is_name_from_file;
113 struct hashether *next;
116 /* internal ethernet type */
118 typedef struct _ether
121 char name[MAXNAMELEN];
124 /* internal ipxnet type */
126 typedef struct _ipxnet
129 char name[MAXNAMELEN];
132 static hashname_t *host_table[HASHHOSTSIZE];
133 static hashname_t *udp_port_table[HASHPORTSIZE];
134 static hashname_t *tcp_port_table[HASHPORTSIZE];
135 static hashether_t *eth_table[HASHETHSIZE];
136 static hashmanuf_t *manuf_table[HASHMANUFSIZE];
137 static hashipxnet_t *ipxnet_table[HASHIPXNETSIZE];
139 static int eth_resolution_initialized = 0;
140 static int ipxnet_resolution_initialized = 0;
143 * Global variables (can be changed in GUI sections)
146 int g_resolving_actif = 1; /* routines are active by default */
148 gchar *g_ethers_path = EPATH_ETHERS;
149 gchar *g_pethers_path = NULL; /* "$HOME"/EPATH_PERSONAL_ETHERS */
150 gchar *g_ipxnets_path = EPATH_IPXNETS;
151 gchar *g_pipxnets_path = NULL; /* "$HOME"/EPATH_PERSONAL_IPXNETS */
152 gchar *g_manuf_path = EPATH_MANUF; /* may only be changed before the */
153 /* first resolving call */
156 * Local function definitions
159 static u_char *serv_name_lookup(u_int port, u_int proto)
164 char *serv_proto = NULL;
165 struct servent *servp;
170 table = udp_port_table;
174 table = tcp_port_table;
178 /* not yet implemented */
184 i = port & (HASHPORTSIZE - 1);
185 tp = table[ i & (HASHPORTSIZE - 1)];
188 tp = table[ i & (HASHPORTSIZE - 1)] =
189 (hashname_t *)g_malloc(sizeof(hashname_t));
192 if( tp->addr == port ) {
195 if (tp->next == NULL) {
196 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
204 /* fill in a new entry */
208 if ((servp = getservbyport(htons(port), serv_proto)) == NULL) {
210 sprintf(tp->name, "%d", port);
212 strncpy(tp->name, servp->s_name, MAXNAMELEN);
213 tp->name[MAXNAMELEN-1] = '\0';
218 } /* serv_name_lookup */
220 #ifdef AVOID_DNS_TIMEOUT
222 #define DNS_TIMEOUT 2 /* max sec per call */
224 jmp_buf hostname_env;
226 static void abort_network_query(int sig)
228 longjmp(hostname_env, 1);
230 #endif /* AVOID_DNS_TIMEOUT */
232 static u_char *host_name_lookup(u_int addr)
235 hashname_t * volatile tp;
236 hashname_t **table = host_table;
237 struct hostent *hostp;
239 tp = table[ addr & (HASHHOSTSIZE - 1)];
242 tp = table[ addr & (HASHHOSTSIZE - 1)] =
243 (hashname_t *)g_malloc(sizeof(hashname_t));
246 if( tp->addr == addr ) {
249 if (tp->next == NULL) {
250 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
258 /* fill in a new entry */
262 #ifdef AVOID_DNS_TIMEOUT
264 /* Quick hack to avoid DNS/YP timeout */
266 if (!setjmp(hostname_env)) {
267 signal(SIGALRM, abort_network_query);
270 hostp = gethostbyaddr((char *)&addr, 4, AF_INET);
271 #ifdef AVOID_DNS_TIMEOUT
275 strncpy(tp->name, hostp->h_name, MAXNAMELEN);
276 tp->name[MAXNAMELEN-1] = '\0';
279 #ifdef AVOID_DNS_TIMEOUT
283 /* unknown host or DNS timeout */
285 sprintf(tp->name, "%s", ip_to_str((guint8 *)&addr));
289 } /* host_name_lookup */
291 static u_char *host_name_lookup6(struct e_in6_addr *addr)
293 static u_char name[MAXNAMELEN];
295 struct hostent *hostp;
297 #ifdef AVOID_DNS_TIMEOUT
299 /* Quick hack to avoid DNS/YP timeout */
301 if (!setjmp(hostname_env)) {
302 signal(SIGALRM, abort_network_query);
304 #endif /* AVOID_DNS_TIMEOUT */
305 hostp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET6);
306 #ifdef AVOID_DNS_TIMEOUT
310 strncpy(name, hostp->h_name, MAXNAMELEN);
311 name[MAXNAMELEN-1] = '\0';
314 #ifdef AVOID_DNS_TIMEOUT
318 /* unknown host or DNS timeout */
320 sprintf(name, "%s", ip6_to_str(addr));
325 * Miscellaneous functions
328 static int fgetline(char **buf, int *size, FILE *fp)
340 if ((*buf = g_malloc(*size)) == NULL)
348 while ((c = getc(fp)) != EOF && c != '\n') {
349 if (len+1 >= *size) {
350 if ((*buf = g_realloc(*buf, *size += BUFSIZ)) == NULL)
356 if (len == 0 && c == EOF)
367 * Ethernet / manufacturer resolution
369 * The following functions implement ethernet address resolution and
370 * ethers files parsing (see ethers(4)).
372 * /etc/manuf has the same format as ethers(4) except that names are
373 * truncated to MAXMANUFLEN-1 characters and that an address contains
374 * only 3 bytes (instead of 6).
378 * I decide to not use the existing functions (see ethers(3) on some
379 * operating systems) for the following reasons:
380 * - performance gains (use of hash tables and some other enhancements),
381 * - use of two ethers files (system-wide and per user),
382 * - avoid the use of NIS maps,
383 * - lack of these functions on some systems.
385 * So the following functions do _not_ behave as the standard ones.
391 static int parse_ether_line(char *line, ether_t *eth, int six_bytes)
394 * See man ethers(4) for /etc/ethers file format
395 * (not available on all systems).
396 * We allow both ethernet address separators (':' and '-'),
397 * as well as Ethereal's '.' separator.
401 int a0, a1, a2, a3, a4, a5;
403 if ((cp = strchr(line, '#')))
406 if ((cp = strtok(line, " \t\n")) == NULL)
410 if (sscanf(cp, "%x:%x:%x:%x:%x:%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6) {
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)
417 if (sscanf(cp, "%x:%x:%x", &a0, &a1, &a2) != 3) {
418 if (sscanf(cp, "%x-%x-%x", &a0, &a1, &a2) != 3) {
419 if (sscanf(cp, "%x.%x.%x", &a0, &a1, &a2) != 3)
425 if ((cp = strtok(NULL, " \t\n")) == NULL)
441 strncpy(eth->name, cp, MAXNAMELEN);
442 eth->name[MAXNAMELEN-1] = '\0';
446 } /* parse_ether_line */
448 static FILE *eth_p = NULL;
450 static void set_ethent(char *path)
455 eth_p = fopen(path, "r");
458 static void end_ethent(void)
466 static ether_t *get_ethent(int six_bytes)
471 static char *buf = NULL;
476 while (fgetline(&buf, &size, eth_p) >= 0) {
477 if (parse_ether_line(buf, ð, six_bytes) == 0) {
486 static ether_t *get_ethbyname(u_char *name)
490 set_ethent(g_ethers_path);
492 while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
498 set_ethent(g_pethers_path);
500 while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
508 } /* get_ethbyname */
510 static ether_t *get_ethbyaddr(const u_char *addr)
515 set_ethent(g_ethers_path);
517 while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
523 set_ethent(g_pethers_path);
525 while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
533 } /* get_ethbyaddr */
535 static void add_manuf_name(u_char *addr, u_char *name)
539 hashmanuf_t **table = manuf_table;
541 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
544 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)] =
545 (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
548 if (tp->next == NULL) {
549 tp->next = (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
557 memcpy(tp->addr, addr, sizeof(tp->addr));
558 strncpy(tp->name, name, MAXMANUFLEN);
559 tp->name[MAXMANUFLEN-1] = '\0';
562 } /* add_manuf_name */
564 static hashmanuf_t *manuf_name_lookup(const u_char *addr)
568 hashmanuf_t **table = manuf_table;
570 tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
573 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
581 } /* manuf_name_lookup */
583 static void initialize_ethers(void)
588 signal(SIGSEGV, SIG_IGN);
591 /* Set g_pethers_path here, but don't actually do anything
592 * with it. It's used in get_ethbyname() and get_ethbyaddr()
594 if (g_pethers_path == NULL) {
595 g_pethers_path = g_malloc(strlen(getenv("HOME")) +
596 strlen(EPATH_PERSONAL_ETHERS) + 2);
597 sprintf(g_pethers_path, "%s/%s",
598 (char *)getenv("HOME"), EPATH_PERSONAL_ETHERS);
601 /* manuf hash table initialization */
603 set_ethent(g_manuf_path);
605 while ((eth = get_ethent(0))) {
606 add_manuf_name(eth->addr, eth->name);
611 } /* initialize_ethers */
613 static hashether_t *add_eth_name(u_char *addr, u_char *name)
616 hashether_t **table = eth_table;
619 j = (addr[2] << 8) | addr[3];
620 i = (addr[4] << 8) | addr[5];
622 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
625 tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
626 (hashether_t *)g_malloc(sizeof(hashether_t));
629 if (tp->next == NULL) {
630 tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
638 memcpy(tp->addr, addr, sizeof(tp->addr));
639 strncpy(tp->name, name, MAXNAMELEN);
640 tp->name[MAXNAMELEN-1] = '\0';
647 static u_char *eth_name_lookup(const u_char *addr)
651 hashether_t **table = eth_table;
655 j = (addr[2] << 8) | addr[3];
656 i = (addr[4] << 8) | addr[5];
658 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
661 tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
662 (hashether_t *)g_malloc(sizeof(hashether_t));
665 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
668 if (tp->next == NULL) {
669 tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
677 /* fill in a new entry */
679 memcpy(tp->addr, addr, sizeof(tp->addr));
682 if ( (eth = get_ethbyaddr(addr)) == NULL) {
685 if ((manufp = manuf_name_lookup(addr)) == NULL)
686 sprintf(tp->name, "%s", ether_to_str((guint8 *)addr));
688 sprintf(tp->name, "%s_%02x:%02x:%02x",
689 manufp->name, addr[3], addr[4], addr[5]);
691 tp->is_name_from_file = FALSE;
694 strncpy(tp->name, eth->name, MAXNAMELEN);
695 tp->name[MAXNAMELEN-1] = '\0';
696 tp->is_name_from_file = TRUE;
701 } /* eth_name_lookup */
703 static u_char *eth_addr_lookup(u_char *name)
707 hashether_t **table = eth_table;
710 /* to be optimized (hash table from name to addr) */
711 for (i = 0; i < HASHETHSIZE; i++) {
714 if (strcmp(tp->name, name) == 0)
720 /* not in hash table : performs a file lookup */
722 if ((eth = get_ethbyname(name)) == NULL)
725 /* add new entry in hash table */
727 tp = add_eth_name(eth->addr, name);
731 } /* eth_addr_lookup */
735 static int parse_ipxnets_line(char *line, ipxnet_t *ipxnet)
738 * We allow three address separators (':', '-', and '.'),
739 * as well as no separators
743 guint32 a, a0, a1, a2, a3;
744 gboolean found_single_number = FALSE;
746 if ((cp = strchr(line, '#')))
749 if ((cp = strtok(line, " \t\n")) == NULL)
752 /* Either fill a0,a1,a2,a3 and found_single_number is FALSE,
753 * fill a and found_single_number is TRUE,
756 if (sscanf(cp, "%x:%x:%x:%x", &a0, &a1, &a2, &a3) != 4) {
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", &a) == 1) {
760 found_single_number = TRUE;
769 if ((cp = strtok(NULL, " \t\n")) == NULL)
772 if (found_single_number) {
776 ipxnet->addr = (a0 << 24) | (a1 << 16) | (a2 << 8) | a3;
779 strncpy(ipxnet->name, cp, MAXNAMELEN);
780 ipxnet->name[MAXNAMELEN-1] = '\0';
784 } /* parse_ipxnets_line */
786 static FILE *ipxnet_p = NULL;
788 static void set_ipxnetent(char *path)
793 ipxnet_p = fopen(path, "r");
796 static void end_ipxnetent(void)
804 static ipxnet_t *get_ipxnetent(void)
807 static ipxnet_t ipxnet;
809 static char *buf = NULL;
811 if (ipxnet_p == NULL)
814 while (fgetline(&buf, &size, ipxnet_p) >= 0) {
815 if (parse_ipxnets_line(buf, &ipxnet) == 0) {
822 } /* get_ipxnetent */
824 static ipxnet_t *get_ipxnetbyname(u_char *name)
828 set_ipxnetent(g_ipxnets_path);
830 while ((ipxnet = get_ipxnetent()) && strncmp(name, ipxnet->name, MAXNAMELEN) != 0)
833 if (ipxnet == NULL) {
836 set_ipxnetent(g_pipxnets_path);
838 while ((ipxnet = get_ipxnetent()) && strncmp(name, ipxnet->name, MAXNAMELEN) != 0)
846 } /* get_ipxnetbyname */
848 static ipxnet_t *get_ipxnetbyaddr(guint32 addr)
853 set_ipxnetent(g_ipxnets_path);
855 while ((ipxnet = get_ipxnetent()) && (addr != ipxnet->addr) ) ;
857 if (ipxnet == NULL) {
860 set_ipxnetent(g_pipxnets_path);
862 while ((ipxnet = get_ipxnetent()) && (addr != ipxnet->addr) )
870 } /* get_ipxnetbyaddr */
872 static void initialize_ipxnets(void)
876 signal(SIGSEGV, SIG_IGN);
879 /* Set g_pipxnets_path here, but don't actually do anything
880 * with it. It's used in get_ipxnetbyname() and get_ipxnetbyaddr()
882 if (g_pipxnets_path == NULL) {
883 g_pipxnets_path = g_malloc(strlen(getenv("HOME")) +
884 strlen(EPATH_PERSONAL_IPXNETS) + 2);
885 sprintf(g_pipxnets_path, "%s/%s",
886 (char *)getenv("HOME"), EPATH_PERSONAL_IPXNETS);
889 } /* initialize_ipxnets */
891 static hashipxnet_t *add_ipxnet_name(u_int addr, u_char *name)
894 hashipxnet_t **table = ipxnet_table;
896 /* XXX - check goodness of hash function */
898 tp = table[ addr & (HASHIPXNETSIZE - 1)];
901 tp = table[ addr & (HASHIPXNETSIZE - 1)] =
902 (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
905 if (tp->next == NULL) {
906 tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
915 strncpy(tp->name, name, MAXNAMELEN);
916 tp->name[MAXNAMELEN-1] = '\0';
921 } /* add_ipxnet_name */
923 static u_char *ipxnet_name_lookup(const u_int addr)
926 hashipxnet_t **table = ipxnet_table;
929 tp = table[ addr & (HASHIPXNETSIZE - 1)];
932 tp = table[ addr & (HASHIPXNETSIZE - 1)] =
933 (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
936 if (tp->addr == addr) {
939 if (tp->next == NULL) {
940 tp->next = (hashipxnet_t *)g_malloc(sizeof(hashipxnet_t));
948 /* fill in a new entry */
953 if ( (ipxnet = get_ipxnetbyaddr(addr)) == NULL) {
955 sprintf(tp->name, "%X", addr);
958 strncpy(tp->name, ipxnet->name, MAXNAMELEN);
959 tp->name[MAXNAMELEN-1] = '\0';
964 } /* ipxnet_name_lookup */
966 static u_int ipxnet_addr_lookup(u_char *name, gboolean *success)
970 hashipxnet_t **table = ipxnet_table;
973 /* to be optimized (hash table from name to addr) */
974 for (i = 0; i < HASHIPXNETSIZE; i++) {
977 if (strcmp(tp->name, name) == 0)
983 /* not in hash table : performs a file lookup */
985 if ((ipxnet = get_ipxnetbyname(name)) == NULL) {
990 /* add new entry in hash table */
992 tp = add_ipxnet_name(ipxnet->addr, name);
997 } /* ipxnet_addr_lookup */
1001 * External Functions
1004 extern u_char *get_hostname(u_int addr)
1006 if (!g_resolving_actif)
1007 return ip_to_str((guint8 *)&addr);
1009 return host_name_lookup(addr);
1012 extern gchar *get_hostname6(struct e_in6_addr *addr)
1015 if (!g_resolving_actif)
1016 return ip6_to_str(addr);
1017 if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MULTICAST(addr))
1018 return ip6_to_str(addr);
1020 return host_name_lookup6(addr);
1023 extern void add_host_name(u_int addr, u_char *name)
1027 hashname_t **table = host_table;
1029 tp = table[ addr & (HASHHOSTSIZE - 1)];
1032 tp = table[ addr & (HASHHOSTSIZE - 1)] =
1033 (hashname_t *)g_malloc(sizeof(hashname_t));
1036 if (tp->next == NULL) {
1037 tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
1045 strncpy(tp->name, name, MAXNAMELEN);
1046 tp->name[MAXNAMELEN-1] = '\0';
1050 } /* add_host_name */
1052 extern u_char *get_udp_port(u_int port)
1054 static gchar str[3][MAXNAMELEN];
1057 if (!g_resolving_actif) {
1058 if (cur == &str[0][0]) {
1060 } else if (cur == &str[1][0]) {
1065 sprintf(cur, "%d", port);
1069 return serv_name_lookup(port, IPPROTO_UDP);
1071 } /* get_udp_port */
1073 extern u_char *get_tcp_port(u_int port)
1075 static gchar str[3][MAXNAMELEN];
1078 if (!g_resolving_actif) {
1079 if (cur == &str[0][0]) {
1081 } else if (cur == &str[1][0]) {
1086 sprintf(cur, "%d", port);
1090 return serv_name_lookup(port, IPPROTO_TCP);
1092 } /* get_tcp_port */
1094 extern u_char *get_ether_name(const u_char *addr)
1096 if (!g_resolving_actif)
1097 return ether_to_str((guint8 *)addr);
1099 if (!eth_resolution_initialized) {
1100 initialize_ethers();
1101 eth_resolution_initialized = 1;
1104 return eth_name_lookup(addr);
1106 } /* get_ether_name */
1108 /* Look for an ether name in the hash, and return it if found.
1109 * If it's not found, simply return NULL. We DO NOT make a new
1110 * hash entry for it with the hex digits turned into a string.
1112 u_char *get_ether_name_if_known(const u_char *addr)
1115 hashether_t **table = eth_table;
1118 /* Initialize ether structs if we're the first
1119 * ether-related function called */
1120 if (!g_resolving_actif)
1123 if (!eth_resolution_initialized) {
1124 initialize_ethers();
1125 eth_resolution_initialized = 1;
1128 j = (addr[2] << 8) | addr[3];
1129 i = (addr[4] << 8) | addr[5];
1131 tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
1134 /* Hash key not found in table.
1135 * Force a lookup (and a hash entry) for addr, then call
1136 * myself. I plan on not getting into an infinite loop because
1137 * eth_name_lookup() is guaranteed to make a hashtable entry,
1138 * so when I call myself again, I can never get into this
1139 * block of code again. Knock on wood...
1141 (void) eth_name_lookup(addr);
1142 return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
1146 if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
1147 if (tp->is_name_from_file) {
1148 /* A name was found, and its origin is an ethers file */
1152 /* A name was found, but it was created, not found in a file */
1156 if (tp->next == NULL) {
1157 /* Read my reason above for why I'm sure I can't get into an infinite loop */
1158 (void) eth_name_lookup(addr);
1159 return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
1164 g_assert_not_reached();
1169 extern u_char *get_ether_addr(u_char *name)
1172 /* force resolution (do not check g_resolving_actif) */
1174 if (!eth_resolution_initialized) {
1175 initialize_ethers();
1176 eth_resolution_initialized = 1;
1179 return eth_addr_lookup(name);
1181 } /* get_ether_addr */
1184 extern u_char *get_ipxnet_name(const guint32 addr)
1187 if (!g_resolving_actif) {
1188 return ipxnet_to_str_punct(addr, '\0');
1191 if (!ipxnet_resolution_initialized) {
1192 initialize_ipxnets();
1193 ipxnet_resolution_initialized = 1;
1196 return ipxnet_name_lookup(addr);
1198 } /* get_ipxnet_name */
1200 extern guint32 get_ipxnet_addr(u_char *name, gboolean *known)
1205 /* force resolution (do not check g_resolving_actif) */
1207 if (!ipxnet_resolution_initialized) {
1208 initialize_ipxnets();
1209 ipxnet_resolution_initialized = 1;
1212 addr = ipxnet_addr_lookup(name, &success);
1217 } /* get_ipxnet_addr */
1219 extern u_char *get_manuf_name(u_char *addr)
1221 static gchar str[3][MAXMANUFLEN];
1223 hashmanuf_t *manufp;
1225 if (g_resolving_actif && !eth_resolution_initialized) {
1226 initialize_ethers();
1227 eth_resolution_initialized = 1;
1230 if (!g_resolving_actif || ((manufp = manuf_name_lookup(addr)) == NULL)) {
1231 if (cur == &str[0][0]) {
1233 } else if (cur == &str[1][0]) {
1238 sprintf(cur, "%02x:%02x:%02x", addr[0], addr[1], addr[2]);
1242 return manufp->name;
1244 } /* get_manuf_name */
1248 /* Translate a string, assumed either to be a dotted-quad IP address or
1249 * a host name, to a numeric IP address. Return TRUE if we succeed and
1250 * set "*addrp" to that numeric IP address; return FALSE if we fail.
1251 * Used more in the dfilter parser rather than in packet dissectors */
1252 gboolean get_host_ipaddr(const char *host, guint32 *addrp)
1254 struct in_addr ipaddr;
1258 * don't change it to inet_pton(AF_INET), they are not 100% compatible.
1259 * inet_pton(AF_INET) does not support hexadecimal notation nor
1260 * less-than-4 octet notation.
1262 if (!inet_aton(host, &ipaddr)) {
1263 /* It's not a valid dotted-quad IP address; is it a valid
1265 hp = gethostbyname(host);
1270 /* XXX - is "hp->h_length" the size of a
1271 * "struct in_addr"? It should be. */
1272 memcpy(&ipaddr, hp->h_addr, hp->h_length);
1276 *addrp = ntohl(ipaddr.s_addr);
1281 * Translate IPv6 numeric address or FQDN hostname, into binary IPv6 address.
1282 * Return TRUE if we succeed and set "*addrp" to that numeric IP address;
1283 * return FALSE if we fail.
1285 gboolean get_host_ipaddr6(const char *host, struct e_in6_addr *addrp)
1289 if (inet_pton(AF_INET6, host, addrp) == 1)
1293 #ifdef HAVE_GETHOSTBYNAME2
1294 hp = gethostbyname2(host, AF_INET6);
1298 if (hp != NULL && hp->h_length == sizeof(struct e_in6_addr)) {
1299 memcpy(addrp, hp->h_addr, hp->h_length);