1998-09-16 02:39:15 +00:00
|
|
|
/* resolv.c
|
|
|
|
* Routines for network object lookup
|
|
|
|
*
|
1999-10-14 05:41:33 +00:00
|
|
|
* $Id: resolv.c,v 1.14 1999/10/14 05:41:33 itojun Exp $
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* Laurent Deniel <deniel@worldnet.fr>
|
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@zing.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
1998-12-17 05:42:33 +00:00
|
|
|
#include <stdlib.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <string.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
#ifndef AVOID_DNS_TIMEOUT
|
|
|
|
#define AVOID_DNS_TIMEOUT
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <unistd.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_NETDB_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <netdb.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
|
|
|
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <signal.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <sys/socket.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
# include <setjmp.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "packet.h"
|
1999-03-28 18:32:03 +00:00
|
|
|
#include "packet-ipv6.h"
|
1999-09-26 14:40:01 +00:00
|
|
|
#include "globals.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "resolv.h"
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
#ifndef MAXNAMELEN
|
1998-09-16 02:39:15 +00:00
|
|
|
#define MAXNAMELEN 64 /* max name length (hostname and port name) */
|
1998-09-25 23:24:07 +00:00
|
|
|
#endif
|
|
|
|
#define MAXMANUFLEN 9 /* max vendor name length with ending '\0' */
|
|
|
|
#define HASHETHSIZE 1024
|
1998-09-16 02:39:15 +00:00
|
|
|
#define HASHHOSTSIZE 1024
|
1998-09-25 23:24:07 +00:00
|
|
|
#define HASHMANUFSIZE 256
|
1998-09-16 02:39:15 +00:00
|
|
|
#define HASHPORTSIZE 256
|
|
|
|
|
|
|
|
/* hash table used for host and port lookup */
|
|
|
|
|
|
|
|
typedef struct hashname {
|
|
|
|
u_int addr;
|
|
|
|
u_char name[MAXNAMELEN];
|
|
|
|
struct hashname *next;
|
|
|
|
} hashname_t;
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/* hash tables used for ethernet and manufacturer lookup */
|
|
|
|
|
|
|
|
typedef struct hashmanuf {
|
|
|
|
u_char addr[3];
|
|
|
|
char name[MAXMANUFLEN];
|
|
|
|
struct hashmanuf *next;
|
|
|
|
} hashmanuf_t;
|
|
|
|
|
|
|
|
typedef struct hashether {
|
|
|
|
u_char addr[6];
|
|
|
|
char name[MAXNAMELEN];
|
|
|
|
struct hashether *next;
|
|
|
|
} hashether_t;
|
|
|
|
|
|
|
|
/* internal ethernet type */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
typedef struct _ether
|
|
|
|
{
|
|
|
|
u_char addr[6];
|
|
|
|
char name[MAXNAMELEN];
|
|
|
|
} ether_t;
|
|
|
|
|
|
|
|
static hashname_t *host_table[HASHHOSTSIZE];
|
|
|
|
static hashname_t *udp_port_table[HASHPORTSIZE];
|
|
|
|
static hashname_t *tcp_port_table[HASHPORTSIZE];
|
|
|
|
static hashether_t *eth_table[HASHETHSIZE];
|
|
|
|
static hashmanuf_t *manuf_table[HASHMANUFSIZE];
|
|
|
|
|
|
|
|
static int eth_resolution_initialized = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Global variables (can be changed in GUI sections)
|
|
|
|
*/
|
|
|
|
|
|
|
|
int g_resolving_actif = 1; /* routines are active by default */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
gchar *g_ethers_path = EPATH_ETHERS;
|
|
|
|
gchar *g_pethers_path = NULL; /* "$HOME"/EPATH_PERSONAL_ETHERS */
|
|
|
|
gchar *g_manuf_path = EPATH_MANUF; /* may only be changed before the */
|
|
|
|
/* first resolving call */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/*
|
|
|
|
* Local function definitions
|
|
|
|
*/
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
static u_char *serv_name_lookup(u_int port, u_int proto)
|
|
|
|
{
|
|
|
|
|
|
|
|
hashname_t *tp;
|
|
|
|
hashname_t **table;
|
|
|
|
char *serv_proto = NULL;
|
|
|
|
struct servent *servp;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
switch(proto) {
|
|
|
|
case IPPROTO_UDP:
|
|
|
|
table = udp_port_table;
|
|
|
|
serv_proto = "udp";
|
|
|
|
break;
|
|
|
|
case IPPROTO_TCP:
|
|
|
|
table = tcp_port_table;
|
|
|
|
serv_proto = "tcp";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* not yet implemented */
|
|
|
|
return NULL;
|
|
|
|
/*NOTREACHED*/
|
|
|
|
break;
|
|
|
|
} /* proto */
|
|
|
|
|
|
|
|
i = port & (HASHPORTSIZE - 1);
|
|
|
|
tp = table[ i & (HASHPORTSIZE - 1)];
|
|
|
|
|
|
|
|
if( tp == NULL ) {
|
|
|
|
tp = table[ i & (HASHPORTSIZE - 1)] =
|
|
|
|
(hashname_t *)g_malloc(sizeof(hashname_t));
|
|
|
|
} else {
|
|
|
|
while(1) {
|
|
|
|
if( tp->addr == port ) {
|
|
|
|
return tp->name;
|
|
|
|
}
|
|
|
|
if (tp->next == NULL) {
|
|
|
|
tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
|
|
|
|
tp = tp->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill in a new entry */
|
|
|
|
tp->addr = port;
|
|
|
|
tp->next = NULL;
|
|
|
|
|
|
|
|
if ((servp = getservbyport(htons(port), serv_proto)) == NULL) {
|
|
|
|
/* unknown port */
|
|
|
|
sprintf(tp->name, "%d", port);
|
|
|
|
} else {
|
|
|
|
strncpy(tp->name, servp->s_name, MAXNAMELEN);
|
1998-09-25 23:24:07 +00:00
|
|
|
tp->name[MAXNAMELEN-1] = '\0';
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (tp->name);
|
|
|
|
|
|
|
|
} /* serv_name_lookup */
|
|
|
|
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
|
1999-09-18 16:01:52 +00:00
|
|
|
#define DNS_TIMEOUT 2 /* max sec per call */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
jmp_buf hostname_env;
|
|
|
|
|
|
|
|
static void abort_network_query(int sig)
|
|
|
|
{
|
|
|
|
longjmp(hostname_env, 1);
|
|
|
|
}
|
|
|
|
#endif /* AVOID_DNS_TIMEOUT */
|
|
|
|
|
|
|
|
static u_char *host_name_lookup(u_int addr)
|
|
|
|
{
|
|
|
|
|
1998-09-27 22:12:47 +00:00
|
|
|
hashname_t * volatile tp;
|
1998-09-16 02:39:15 +00:00
|
|
|
hashname_t **table = host_table;
|
|
|
|
struct hostent *hostp;
|
|
|
|
|
|
|
|
tp = table[ addr & (HASHHOSTSIZE - 1)];
|
|
|
|
|
|
|
|
if( tp == NULL ) {
|
|
|
|
tp = table[ addr & (HASHHOSTSIZE - 1)] =
|
|
|
|
(hashname_t *)g_malloc(sizeof(hashname_t));
|
|
|
|
} else {
|
|
|
|
while(1) {
|
|
|
|
if( tp->addr == addr ) {
|
|
|
|
return tp->name;
|
|
|
|
}
|
|
|
|
if (tp->next == NULL) {
|
|
|
|
tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
|
|
|
|
tp = tp->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill in a new entry */
|
|
|
|
tp->addr = addr;
|
|
|
|
tp->next = NULL;
|
|
|
|
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
1998-09-25 23:24:07 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Quick hack to avoid DNS/YP timeout */
|
1998-09-25 23:24:07 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
if (!setjmp(hostname_env)) {
|
|
|
|
signal(SIGALRM, abort_network_query);
|
|
|
|
alarm(DNS_TIMEOUT);
|
|
|
|
#endif
|
|
|
|
hostp = gethostbyaddr((char *)&addr, 4, AF_INET);
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
alarm(0);
|
|
|
|
#endif
|
|
|
|
if (hostp != NULL) {
|
|
|
|
strncpy(tp->name, hostp->h_name, MAXNAMELEN);
|
1998-09-25 23:24:07 +00:00
|
|
|
tp->name[MAXNAMELEN-1] = '\0';
|
1998-09-16 02:39:15 +00:00
|
|
|
return tp->name;
|
|
|
|
}
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* unknown host or DNS timeout */
|
|
|
|
|
|
|
|
sprintf(tp->name, "%s", ip_to_str((guint8 *)&addr));
|
1998-09-25 23:24:07 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
return (tp->name);
|
|
|
|
|
|
|
|
} /* host_name_lookup */
|
|
|
|
|
1999-03-28 18:32:03 +00:00
|
|
|
static u_char *host_name_lookup6(struct e_in6_addr *addr)
|
|
|
|
{
|
|
|
|
static u_char name[MAXNAMELEN];
|
|
|
|
#ifdef INET6
|
|
|
|
struct hostent *hostp;
|
|
|
|
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
|
|
|
|
/* Quick hack to avoid DNS/YP timeout */
|
|
|
|
|
|
|
|
if (!setjmp(hostname_env)) {
|
|
|
|
signal(SIGALRM, abort_network_query);
|
|
|
|
alarm(DNS_TIMEOUT);
|
|
|
|
#endif /* AVOID_DNS_TIMEOUT */
|
|
|
|
hostp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET6);
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
alarm(0);
|
|
|
|
#endif
|
|
|
|
if (hostp != NULL) {
|
|
|
|
strncpy(name, hostp->h_name, MAXNAMELEN);
|
|
|
|
name[MAXNAMELEN-1] = '\0';
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
#ifdef AVOID_DNS_TIMEOUT
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* unknown host or DNS timeout */
|
|
|
|
#endif /* INET6 */
|
|
|
|
sprintf(name, "%s", ip6_to_str(addr));
|
|
|
|
return (name);
|
|
|
|
}
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
/*
|
|
|
|
* Miscellaneous functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int fgetline(char **buf, int *size, FILE *fp)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
int c;
|
|
|
|
|
|
|
|
if (fp == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (*buf == NULL) {
|
|
|
|
if (*size == 0)
|
|
|
|
*size = BUFSIZ;
|
|
|
|
|
|
|
|
if ((*buf = g_malloc(*size)) == NULL)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (feof(fp))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
len = 0;
|
|
|
|
while ((c = getc(fp)) != EOF && c != '\n') {
|
|
|
|
if (len+1 >= *size) {
|
|
|
|
if ((*buf = g_realloc(*buf, *size += BUFSIZ)) == NULL)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
(*buf)[len++] = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len == 0 && c == EOF)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
(*buf)[len] = '\0';
|
|
|
|
|
|
|
|
return len;
|
|
|
|
|
|
|
|
} /* fgetline */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ethernet / manufacturer resolution
|
|
|
|
*
|
|
|
|
* The following functions implement ethernet address resolution and
|
|
|
|
* ethers files parsing (see ethers(4)).
|
|
|
|
*
|
|
|
|
* /etc/manuf has the same format as ethers(4) except that names are
|
|
|
|
* truncated to MAXMANUFLEN-1 characters and that an address contains
|
|
|
|
* only 3 bytes (instead of 6).
|
|
|
|
*
|
|
|
|
* Notes:
|
|
|
|
*
|
|
|
|
* I decide to not use the existing functions (see ethers(3) on some
|
|
|
|
* operating systems) for the following reasons:
|
|
|
|
* - performance gains (use of hash tables and some other enhancements),
|
|
|
|
* - use of two ethers files (system-wide and per user),
|
|
|
|
* - avoid the use of NIS maps,
|
|
|
|
* - lack of these functions on some systems.
|
|
|
|
*
|
|
|
|
* So the following functions do _not_ behave as the standard ones.
|
|
|
|
*
|
|
|
|
* -- Laurent.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static int parse_ether_line(char *line, ether_t *eth, int six_bytes)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* See man ethers(4) for /etc/ethers file format
|
|
|
|
* (not available on all systems).
|
|
|
|
* We allow both ethernet address separators (':' and '-').
|
|
|
|
*/
|
|
|
|
|
|
|
|
gchar *cp;
|
|
|
|
int a0, a1, a2, a3, a4, a5;
|
|
|
|
|
|
|
|
if ((cp = strchr(line, '#')))
|
|
|
|
*cp = '\0';
|
|
|
|
|
|
|
|
if ((cp = strtok(line, " \t\n")) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (six_bytes) {
|
|
|
|
if (sscanf(cp, "%x:%x:%x:%x:%x:%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6) {
|
|
|
|
if (sscanf(cp, "%x-%x-%x-%x-%x-%x", &a0, &a1, &a2, &a3, &a4, &a5) != 6)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (sscanf(cp, "%x:%x:%x", &a0, &a1, &a2) != 3) {
|
|
|
|
if (sscanf(cp, "%x-%x-%x", &a0, &a1, &a2) != 3)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((cp = strtok(NULL, " \t\n")) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
eth->addr[0] = a0;
|
|
|
|
eth->addr[1] = a1;
|
|
|
|
eth->addr[2] = a2;
|
|
|
|
if (six_bytes) {
|
|
|
|
eth->addr[3] = a3;
|
|
|
|
eth->addr[4] = a4;
|
|
|
|
eth->addr[5] = a5;
|
|
|
|
} else {
|
|
|
|
eth->addr[3] = 0;
|
|
|
|
eth->addr[4] = 0;
|
|
|
|
eth->addr[5] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(eth->name, cp, MAXNAMELEN);
|
|
|
|
eth->name[MAXNAMELEN-1] = '\0';
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} /* parse_ether_line */
|
|
|
|
|
|
|
|
static FILE *eth_p = NULL;
|
|
|
|
|
|
|
|
static void set_ethent(char *path)
|
|
|
|
{
|
|
|
|
if (eth_p)
|
|
|
|
rewind(eth_p);
|
|
|
|
else
|
|
|
|
eth_p = fopen(path, "r");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void end_ethent(void)
|
|
|
|
{
|
|
|
|
if (eth_p) {
|
|
|
|
fclose(eth_p);
|
|
|
|
eth_p = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static ether_t *get_ethent(int six_bytes)
|
|
|
|
{
|
|
|
|
|
|
|
|
static ether_t eth;
|
|
|
|
static int size = 0;
|
|
|
|
static char *buf = NULL;
|
|
|
|
|
|
|
|
if (eth_p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
while (fgetline(&buf, &size, eth_p) >= 0) {
|
|
|
|
if (parse_ether_line(buf, ð, six_bytes) == 0) {
|
|
|
|
return ð
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
} /* get_ethent */
|
|
|
|
|
|
|
|
static ether_t *get_ethbyname(u_char *name)
|
|
|
|
{
|
|
|
|
ether_t *eth;
|
|
|
|
|
|
|
|
set_ethent(g_ethers_path);
|
|
|
|
|
|
|
|
while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
|
|
|
|
;
|
|
|
|
|
|
|
|
if (eth == NULL) {
|
|
|
|
end_ethent();
|
|
|
|
|
|
|
|
set_ethent(g_pethers_path);
|
|
|
|
|
|
|
|
while ((eth = get_ethent(1)) && strncmp(name, eth->name, MAXNAMELEN) != 0)
|
|
|
|
;
|
|
|
|
|
|
|
|
end_ethent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return eth;
|
|
|
|
|
|
|
|
} /* get_ethbyname */
|
|
|
|
|
|
|
|
static ether_t *get_ethbyaddr(u_char *addr)
|
|
|
|
{
|
|
|
|
|
|
|
|
ether_t *eth;
|
|
|
|
|
|
|
|
set_ethent(g_ethers_path);
|
|
|
|
|
|
|
|
while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
|
|
|
|
;
|
|
|
|
|
|
|
|
if (eth == NULL) {
|
|
|
|
end_ethent();
|
|
|
|
|
|
|
|
set_ethent(g_pethers_path);
|
|
|
|
|
|
|
|
while ((eth = get_ethent(1)) && memcmp(addr, eth->addr, 6) != 0)
|
|
|
|
;
|
|
|
|
|
|
|
|
end_ethent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return eth;
|
|
|
|
|
|
|
|
} /* get_ethbyaddr */
|
|
|
|
|
|
|
|
static void add_manuf_name(u_char *addr, u_char *name)
|
|
|
|
{
|
|
|
|
|
|
|
|
hashmanuf_t *tp;
|
|
|
|
hashmanuf_t **table = manuf_table;
|
|
|
|
|
|
|
|
tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
|
|
|
|
|
|
|
|
if( tp == NULL ) {
|
|
|
|
tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)] =
|
|
|
|
(hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
|
|
|
|
} else {
|
|
|
|
while(1) {
|
|
|
|
if (tp->next == NULL) {
|
|
|
|
tp->next = (hashmanuf_t *)g_malloc(sizeof(hashmanuf_t));
|
|
|
|
tp = tp->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(tp->addr, addr, sizeof(tp->addr));
|
|
|
|
strncpy(tp->name, name, MAXMANUFLEN);
|
|
|
|
tp->name[MAXMANUFLEN-1] = '\0';
|
|
|
|
tp->next = NULL;
|
|
|
|
|
|
|
|
} /* add_manuf_name */
|
|
|
|
|
|
|
|
static hashmanuf_t *manuf_name_lookup(u_char *addr)
|
|
|
|
{
|
|
|
|
|
|
|
|
hashmanuf_t *tp;
|
|
|
|
hashmanuf_t **table = manuf_table;
|
|
|
|
|
|
|
|
tp = table[ ((int)addr[2]) & (HASHMANUFSIZE - 1)];
|
|
|
|
|
|
|
|
while(tp != NULL) {
|
|
|
|
if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
|
|
|
|
return tp;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
} /* manuf_name_lookup */
|
|
|
|
|
|
|
|
static hashether_t *add_eth_name(u_char *addr, u_char *name)
|
|
|
|
{
|
|
|
|
hashether_t *tp;
|
|
|
|
hashether_t **table = eth_table;
|
|
|
|
int i,j;
|
|
|
|
|
|
|
|
j = (addr[2] << 8) | addr[3];
|
|
|
|
i = (addr[4] << 8) | addr[5];
|
|
|
|
|
|
|
|
tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
|
|
|
|
|
|
|
|
if( tp == NULL ) {
|
|
|
|
tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
|
|
|
|
(hashether_t *)g_malloc(sizeof(hashether_t));
|
|
|
|
} else {
|
|
|
|
while(1) {
|
|
|
|
if (tp->next == NULL) {
|
|
|
|
tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
|
|
|
|
tp = tp->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(tp->addr, addr, sizeof(tp->addr));
|
|
|
|
strncpy(tp->name, name, MAXNAMELEN);
|
|
|
|
tp->name[MAXNAMELEN-1] = '\0';
|
|
|
|
tp->next = NULL;
|
|
|
|
|
|
|
|
return tp;
|
|
|
|
|
|
|
|
} /* add_eth_name */
|
|
|
|
|
|
|
|
static u_char *eth_name_lookup(u_char *addr)
|
|
|
|
{
|
|
|
|
hashmanuf_t *manufp;
|
|
|
|
hashether_t *tp;
|
|
|
|
hashether_t **table = eth_table;
|
|
|
|
ether_t *eth;
|
|
|
|
int i,j;
|
|
|
|
|
|
|
|
j = (addr[2] << 8) | addr[3];
|
|
|
|
i = (addr[4] << 8) | addr[5];
|
|
|
|
|
|
|
|
tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
|
|
|
|
|
|
|
|
if( tp == NULL ) {
|
|
|
|
tp = table[ (i ^ j) & (HASHETHSIZE - 1)] =
|
|
|
|
(hashether_t *)g_malloc(sizeof(hashether_t));
|
|
|
|
} else {
|
|
|
|
while(1) {
|
|
|
|
if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
|
|
|
|
return tp->name;
|
|
|
|
}
|
|
|
|
if (tp->next == NULL) {
|
|
|
|
tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
|
|
|
|
tp = tp->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill in a new entry */
|
|
|
|
|
|
|
|
memcpy(tp->addr, addr, sizeof(tp->addr));
|
|
|
|
tp->next = NULL;
|
|
|
|
|
|
|
|
if ( (eth = get_ethbyaddr(addr)) == NULL) {
|
|
|
|
/* unknown name */
|
|
|
|
|
|
|
|
if ((manufp = manuf_name_lookup(addr)) == NULL)
|
|
|
|
sprintf(tp->name, "%s", ether_to_str((guint8 *)addr));
|
|
|
|
else
|
|
|
|
sprintf(tp->name, "%s_%02x:%02x:%02x",
|
|
|
|
manufp->name, addr[3], addr[4], addr[5]);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
strncpy(tp->name, eth->name, MAXNAMELEN);
|
|
|
|
tp->name[MAXNAMELEN-1] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
return (tp->name);
|
|
|
|
|
|
|
|
} /* eth_name_lookup */
|
|
|
|
|
|
|
|
static u_char *eth_addr_lookup(u_char *name)
|
|
|
|
{
|
|
|
|
ether_t *eth;
|
|
|
|
hashether_t *tp;
|
|
|
|
hashether_t **table = eth_table;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* to be optimized (hash table from name to addr) */
|
|
|
|
for (i = 0; i < HASHETHSIZE; i++) {
|
|
|
|
tp = table[i];
|
|
|
|
while (tp) {
|
|
|
|
if (strcmp(tp->name, name) == 0)
|
|
|
|
return tp->addr;
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* not in hash table : performs a file lookup */
|
|
|
|
|
|
|
|
if ((eth = get_ethbyname(name)) == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* add new entry in hash table */
|
|
|
|
|
|
|
|
tp = add_eth_name(eth->addr, name);
|
|
|
|
|
|
|
|
return tp->addr;
|
|
|
|
|
|
|
|
} /* eth_addr_lookup */
|
|
|
|
|
|
|
|
static void initialize_ethers(void)
|
|
|
|
{
|
|
|
|
ether_t *eth;
|
|
|
|
|
|
|
|
#ifdef DEBUG_RESOLV
|
|
|
|
signal(SIGSEGV, SIG_IGN);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (g_pethers_path == NULL) {
|
|
|
|
g_pethers_path = g_malloc(strlen(getenv("HOME")) +
|
|
|
|
strlen(EPATH_PERSONAL_ETHERS) + 2);
|
|
|
|
sprintf(g_pethers_path, "%s/%s",
|
|
|
|
(char *)getenv("HOME"), EPATH_PERSONAL_ETHERS);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* manuf hash table initialization */
|
|
|
|
|
|
|
|
set_ethent(g_manuf_path);
|
|
|
|
|
|
|
|
while ((eth = get_ethent(0))) {
|
|
|
|
add_manuf_name(eth->addr, eth->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
end_ethent();
|
|
|
|
|
|
|
|
} /* initialize_ethers */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* External Functions
|
|
|
|
*/
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
extern u_char *get_hostname(u_int addr)
|
|
|
|
{
|
|
|
|
if (!g_resolving_actif)
|
|
|
|
return ip_to_str((guint8 *)&addr);
|
|
|
|
|
|
|
|
return host_name_lookup(addr);
|
|
|
|
}
|
|
|
|
|
1999-03-28 18:32:03 +00:00
|
|
|
extern gchar *get_hostname6(struct e_in6_addr *addr)
|
|
|
|
{
|
|
|
|
#ifdef INET6
|
|
|
|
if (!g_resolving_actif)
|
|
|
|
return ip6_to_str(addr);
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MULTICAST(addr))
|
|
|
|
return ip6_to_str(addr);
|
|
|
|
#endif
|
|
|
|
return host_name_lookup6(addr);
|
|
|
|
}
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
extern void add_host_name(u_int addr, u_char *name)
|
|
|
|
{
|
|
|
|
|
|
|
|
hashname_t *tp;
|
|
|
|
hashname_t **table = host_table;
|
|
|
|
|
|
|
|
tp = table[ addr & (HASHHOSTSIZE - 1)];
|
|
|
|
|
|
|
|
if( tp == NULL ) {
|
|
|
|
tp = table[ addr & (HASHHOSTSIZE - 1)] =
|
|
|
|
(hashname_t *)g_malloc(sizeof(hashname_t));
|
|
|
|
} else {
|
|
|
|
while(1) {
|
|
|
|
if (tp->next == NULL) {
|
|
|
|
tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
|
|
|
|
tp = tp->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tp = tp->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(tp->name, name, MAXNAMELEN);
|
|
|
|
tp->name[MAXNAMELEN-1] = '\0';
|
|
|
|
tp->addr = addr;
|
|
|
|
tp->next = NULL;
|
|
|
|
|
|
|
|
} /* add_host_name */
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
extern u_char *get_udp_port(u_int port)
|
|
|
|
{
|
|
|
|
static gchar str[3][MAXNAMELEN];
|
|
|
|
static gchar *cur;
|
|
|
|
|
|
|
|
if (!g_resolving_actif) {
|
|
|
|
if (cur == &str[0][0]) {
|
|
|
|
cur = &str[1][0];
|
|
|
|
} else if (cur == &str[1][0]) {
|
|
|
|
cur = &str[2][0];
|
|
|
|
} else {
|
|
|
|
cur = &str[0][0];
|
|
|
|
}
|
|
|
|
sprintf(cur, "%d", port);
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
return serv_name_lookup(port, IPPROTO_UDP);
|
|
|
|
|
|
|
|
} /* get_udp_port */
|
|
|
|
|
|
|
|
extern u_char *get_tcp_port(u_int port)
|
|
|
|
{
|
|
|
|
static gchar str[3][MAXNAMELEN];
|
|
|
|
static gchar *cur;
|
|
|
|
|
|
|
|
if (!g_resolving_actif) {
|
|
|
|
if (cur == &str[0][0]) {
|
|
|
|
cur = &str[1][0];
|
|
|
|
} else if (cur == &str[1][0]) {
|
|
|
|
cur = &str[2][0];
|
|
|
|
} else {
|
|
|
|
cur = &str[0][0];
|
|
|
|
}
|
|
|
|
sprintf(cur, "%d", port);
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
return serv_name_lookup(port, IPPROTO_TCP);
|
|
|
|
|
|
|
|
} /* get_tcp_port */
|
|
|
|
|
1998-09-25 23:24:07 +00:00
|
|
|
extern u_char *get_ether_name(u_char *addr)
|
|
|
|
{
|
|
|
|
if (!g_resolving_actif)
|
|
|
|
return ether_to_str((guint8 *)addr);
|
|
|
|
|
|
|
|
if (!eth_resolution_initialized) {
|
|
|
|
initialize_ethers();
|
|
|
|
eth_resolution_initialized = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eth_name_lookup(addr);
|
|
|
|
|
|
|
|
} /* get_ether_name */
|
|
|
|
|
|
|
|
extern u_char *get_ether_addr(u_char *name)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* force resolution (do not check g_resolving_actif) */
|
|
|
|
|
|
|
|
if (!eth_resolution_initialized) {
|
|
|
|
initialize_ethers();
|
|
|
|
eth_resolution_initialized = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eth_addr_lookup(name);
|
|
|
|
|
|
|
|
} /* get_ether_addr */
|
|
|
|
|
|
|
|
extern u_char *get_manuf_name(u_char *addr)
|
|
|
|
{
|
|
|
|
static gchar str[3][MAXMANUFLEN];
|
|
|
|
static gchar *cur;
|
|
|
|
hashmanuf_t *manufp;
|
|
|
|
|
|
|
|
if (g_resolving_actif && !eth_resolution_initialized) {
|
|
|
|
initialize_ethers();
|
|
|
|
eth_resolution_initialized = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_resolving_actif || ((manufp = manuf_name_lookup(addr)) == NULL)) {
|
|
|
|
if (cur == &str[0][0]) {
|
|
|
|
cur = &str[1][0];
|
|
|
|
} else if (cur == &str[1][0]) {
|
|
|
|
cur = &str[2][0];
|
|
|
|
} else {
|
|
|
|
cur = &str[0][0];
|
|
|
|
}
|
|
|
|
sprintf(cur, "%02x:%02x:%02x", addr[0], addr[1], addr[2]);
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
return manufp->name;
|
|
|
|
|
|
|
|
} /* get_manuf_name */
|
1999-07-07 22:52:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
/* Translate a string, assumed either to be a dotted-quad IP address or
|
|
|
|
* a host name, to a numeric IP address. Return TRUE if we succeed and
|
|
|
|
* set "*addrp" to that numeric IP address; return FALSE if we fail.
|
1999-07-07 22:52:57 +00:00
|
|
|
* Used more in the dfilter parser rather than in packet dissectors */
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
gboolean get_host_ipaddr(const char *host, guint32 *addrp)
|
1999-07-07 22:52:57 +00:00
|
|
|
{
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
struct in_addr ipaddr;
|
|
|
|
struct hostent *hp;
|
1999-07-07 22:52:57 +00:00
|
|
|
|
1999-10-14 05:41:33 +00:00
|
|
|
/*
|
|
|
|
* don't change it to inet_pton(AF_INET), they are not 100% compatible.
|
|
|
|
* inet_pton(AF_INET) does not support hexadecimal notation nor
|
|
|
|
* less-than-4 octet notation.
|
|
|
|
*/
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
if (!inet_aton(host, &ipaddr)) {
|
|
|
|
/* It's not a valid dotted-quad IP address; is it a valid
|
|
|
|
* host name? */
|
|
|
|
hp = gethostbyname(host);
|
1999-07-07 22:52:57 +00:00
|
|
|
if (hp == NULL) {
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
/* No. */
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
/* XXX - is "hp->h_length" the size of a
|
|
|
|
* "struct in_addr"? It should be. */
|
|
|
|
memcpy(&ipaddr, hp->h_addr, hp->h_length);
|
1999-07-07 22:52:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Have "get_host_ipaddr()" return a Boolean indicating whether it
succeeded or failed, and, if it succeeded, have it fill in the IP
address if found through a pointer passed as the second argument.
Have it first try interpreting its first argument as a dotted-quad IP
address, with "inet_aton()", and, if that fails, have it try to
interpret it as a host name with "gethostbyname()"; don't bother with
"gethostbyaddr()", as we should be allowed to filter on IP addresses
even if there's no host name associated with them (there's no guarantee
that "gethostbyaddr()" will succeed if handed an IP address with no
corresponding name - and it looks as if FreeBSD 3.2, at least, may not
succeed in that case).
Add a "dfilter_fail()" routine that takes "printf()"-like arguments and
uses them to set an error message for the parse; doing so means that
even if the filter expression is syntactically valid, we treat it as
being invalid. (Is there a better way to force a parse to fail from
arbitrary places in routines called by the parser?)
Use that routine in the lexical analyzer.
If that error message was set, use it as is as the failure message,
rather than adding "Unable to parse filter string XXX" to it.
Have the code to handle IP addresses and host names in display filters
check whether "get_host_ipaddr()" succeeded or failed and, if it failed,
arrange that the parse fail with an error message indicating the source
of the problem.
svn path=/trunk/; revision=802
1999-10-11 03:03:12 +00:00
|
|
|
*addrp = ntohl(ipaddr.s_addr);
|
|
|
|
return TRUE;
|
1999-07-07 22:52:57 +00:00
|
|
|
}
|
1999-10-14 05:41:33 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Translate IPv6 numeric address or FQDN hostname, into binary IPv6 address.
|
|
|
|
* Return TRUE if we succeed and set "*addrp" to that numeric IP address;
|
|
|
|
* return FALSE if we fail.
|
|
|
|
*/
|
|
|
|
gboolean get_host_ipaddr6(const char *host, struct e_in6_addr *addrp)
|
|
|
|
{
|
|
|
|
struct hostent *hp;
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET6, host, addrp) == 1)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* try FQDN */
|
|
|
|
#ifdef HAVE_GETHOSTBYNAME2
|
|
|
|
hp = gethostbyname2(host, AF_INET6);
|
|
|
|
#else
|
|
|
|
hp = NULL;
|
|
|
|
#endif
|
|
|
|
if (hp != NULL && hp->h_length == sizeof(struct e_in6_addr)) {
|
|
|
|
memcpy(addrp, hp->h_addr, hp->h_length);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|