aboutsummaryrefslogtreecommitdiffstats
path: root/epan/addr_resolv.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-11-17 09:44:41 +0000
committerGuy Harris <guy@alum.mit.edu>2004-11-17 09:44:41 +0000
commit4469052ec34d352f908d0494fbc91e77e6b162c9 (patch)
tree7c4737b119d2f4852999ec1b9a934feec62bdb8a /epan/addr_resolv.c
parent366ff47474d051503bd76518b92d84b79e3b087f (diff)
Add a hash table for IPv6 addresses, and add an "add_ipv6_name()"
routine to add IPv6-address/name pairings to that table; use that when reading the hosts file. svn path=/trunk/; revision=12537
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r--epan/addr_resolv.c118
1 files changed, 105 insertions, 13 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index 5e0fd7eac2..fbf37eea16 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -133,10 +133,21 @@
typedef struct hashipv4 {
guint addr;
gchar name[MAXNAMELEN];
- gboolean is_dummy_entry; /* name is IP address in dot format */
+ gboolean is_dummy_entry; /* name is IPv4 address in dot format */
struct hashipv4 *next;
} hashipv4_t;
+/* hash table used for IPv6 lookup */
+
+#define HASH_IPV6_ADDRESS(addr) (((addr).s6_addr32[3]) & (HASHHOSTSIZE - 1))
+
+typedef struct hashipv6 {
+ struct e_in6_addr addr;
+ gchar name[MAXNAMELEN];
+ gboolean is_dummy_entry; /* name is IPv6 address in colon format */
+ struct hashipv6 *next;
+} hashipv6_t;
+
/* hash table used for TCP/UDP/SCTP port lookup */
#define HASH_PORT(port) ((port) & (HASHPORTSIZE - 1))
@@ -197,6 +208,7 @@ typedef struct _ipxnet
} ipxnet_t;
static hashipv4_t *ipv4_table[HASHHOSTSIZE];
+static hashipv6_t *ipv6_table[HASHHOSTSIZE];
static hashport_t *udp_port_table[HASHPORTSIZE];
static hashport_t *tcp_port_table[HASHPORTSIZE];
static hashport_t *sctp_port_table[HASHPORTSIZE];
@@ -435,10 +447,39 @@ static gchar *host_name_lookup(guint addr, gboolean *found)
static gchar *host_name_lookup6(struct e_in6_addr *addr, gboolean *found)
{
- static gchar name[MAXNAMELEN];
#ifdef INET6
+ int hash_idx;
+ hashipv6_t * volatile tp;
struct hostent *hostp;
+ *found = TRUE;
+
+ hash_idx = HASH_IPV6_ADDRESS(*addr);
+
+ tp = ipv6_table[hash_idx];
+
+ if( tp == NULL ) {
+ tp = ipv6_table[hash_idx] = (hashipv6_t *)g_malloc(sizeof(hashipv6_t));
+ } else {
+ while(1) {
+ if( memcmp(&tp->addr, addr, sizeof (struct e_in6_addr)) == 0 ) {
+ if (tp->is_dummy_entry)
+ *found = FALSE;
+ return tp->name;
+ }
+ if (tp->next == NULL) {
+ tp->next = (hashipv6_t *)g_malloc(sizeof(hashipv6_t));
+ tp = tp->next;
+ break;
+ }
+ tp = tp->next;
+ }
+ }
+
+ /* fill in a new entry */
+ tp->addr = *addr;
+ tp->next = NULL;
+
if (g_resolv_flags & RESOLV_NETWORK) {
#ifdef AVOID_DNS_TIMEOUT
@@ -451,24 +492,29 @@ static gchar *host_name_lookup6(struct e_in6_addr *addr, gboolean *found)
hostp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET6);
#ifdef AVOID_DNS_TIMEOUT
alarm(0);
-#endif
+# endif /* AVOID_DNS_TIMEOUT */
+
if (hostp != NULL) {
- strncpy(name, hostp->h_name, MAXNAMELEN);
- name[MAXNAMELEN-1] = '\0';
- *found = TRUE;
- return name;
+ strncpy(tp->name, hostp->h_name, MAXNAMELEN);
+ tp->name[MAXNAMELEN-1] = '\0';
+ tp->is_dummy_entry = FALSE;
+ return tp->name;
}
+
#ifdef AVOID_DNS_TIMEOUT
}
-#endif
+# endif /* AVOID_DNS_TIMEOUT */
+
}
/* unknown host or DNS timeout */
#endif /* INET6 */
+ ip6_to_str_buf(addr, tp->name);
+ tp->is_dummy_entry = TRUE;
*found = FALSE;
- ip6_to_str_buf(addr, name);
- return (name);
-}
+ return (tp->name);
+
+} /* host_name_lookup6 */
/*
* Miscellaneous functions
@@ -1462,6 +1508,7 @@ read_hosts_file (FILE *hf)
int size = 0;
gchar *cp;
guint32 host_addr[4]; /* IPv4 or IPv6 */
+ struct e_in6_addr ipv6_addr;
gboolean is_ipv6;
int ret;
@@ -1492,14 +1539,20 @@ read_hosts_file (FILE *hf)
if ((cp = strtok(NULL, " \t")) == NULL)
continue; /* no host name */
- if (!is_ipv6)
+ if (is_ipv6) {
+ memcpy(&ipv6_addr, host_addr, sizeof ipv6_addr);
+ add_ipv6_name(&ipv6_addr, cp);
+ } else
add_ipv4_name(host_addr[0], cp);
/*
* Add the aliases, too, if there are any.
*/
while ((cp = strtok(NULL, " \t")) != NULL) {
- if (!is_ipv6)
+ if (is_ipv6) {
+ memcpy(&ipv6_addr, host_addr, sizeof ipv6_addr);
+ add_ipv6_name(&ipv6_addr, cp);
+ } else
add_ipv4_name(host_addr[0], cp);
}
}
@@ -1711,6 +1764,45 @@ extern void add_ipv4_name(guint addr, const gchar *name)
} /* add_ipv4_name */
+extern void add_ipv6_name(struct e_in6_addr *addrp, const gchar *name)
+{
+ int hash_idx;
+ hashipv6_t *tp;
+
+ hash_idx = HASH_IPV6_ADDRESS(*addrp);
+
+ tp = ipv6_table[hash_idx];
+
+ if( tp == NULL ) {
+ tp = ipv6_table[hash_idx] = (hashipv6_t *)g_malloc(sizeof(hashipv6_t));
+ } else {
+ while(1) {
+ if (memcmp(&tp->addr, addrp, sizeof (struct e_in6_addr)) == 0) {
+ /* address already known */
+ if (!tp->is_dummy_entry) {
+ return;
+ } else {
+ /* replace this dummy entry with the new one */
+ break;
+ }
+ }
+ if (tp->next == NULL) {
+ tp->next = (hashipv6_t *)g_malloc(sizeof(hashipv6_t));
+ tp = tp->next;
+ break;
+ }
+ tp = tp->next;
+ }
+ }
+
+ strncpy(tp->name, name, MAXNAMELEN);
+ tp->name[MAXNAMELEN-1] = '\0';
+ tp->addr = *addrp;
+ tp->next = NULL;
+ tp->is_dummy_entry = FALSE;
+
+} /* add_ipv6_name */
+
extern gchar *get_udp_port(guint port)
{
static gchar str[3][MAXNAMELEN];