]> The Tcpdump Group git mirrors - libpcap/blobdiff - nametoaddr.c
pcap_create_interface() needs the interface name on Linux.
[libpcap] / nametoaddr.c
index 70b64ce53359efd1ac46970604d34a2809f84069..71280b31c48d73cd46af38c7aee240e10ef60ad0 100644 (file)
  * These functions are not time critical.
  */
 
  * These functions are not time critical.
  */
 
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.72 2003-12-24 08:27:04 itojun Exp $ (LBL)";
-#endif
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#ifdef WIN32
+#ifdef DECNETLIB
+#include <sys/types.h>
+#include <netdnet/dnetdb.h>
+#endif
+
+#ifdef _WIN32
 #include <pcap-stdinc.h>
 
 #include <pcap-stdinc.h>
 
-#else /* WIN32 */
+#ifdef INET6
+/*
+ * To quote the MSDN page for getaddrinfo() at
+ *
+ *    https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
+ *
+ * "Support for getaddrinfo on Windows 2000 and older versions
+ * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
+ * later. To execute an application that uses this function on earlier
+ * versions of Windows, then you need to include the Ws2tcpip.h and
+ * Wspiapi.h files. When the Wspiapi.h include file is added, the
+ * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
+ * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
+ * function is implemented in such a way that if the Ws2_32.dll or the
+ * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
+ * Preview for Windows 2000) does not include getaddrinfo, then a
+ * version of getaddrinfo is implemented inline based on code in the
+ * Wspiapi.h header file. This inline code will be used on older Windows
+ * platforms that do not natively support the getaddrinfo function."
+ *
+ * We use getaddrinfo(), so we include Wspiapi.h here.  pcap-stdinc.h
+ * includes Ws2tcpip.h, so we don't need to include it ourselves.
+ */
+#include <Wspiapi.h>
+#endif
+
+#else /* _WIN32 */
 
 #include <sys/param.h>
 #include <sys/types.h>                         /* concession to AIX */
 
 #include <sys/param.h>
 #include <sys/types.h>                         /* concession to AIX */
@@ -42,38 +68,39 @@ static const char rcsid[] _U_ =
 #include <sys/time.h>
 
 #include <netinet/in.h>
 #include <sys/time.h>
 
 #include <netinet/in.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
 
 
+#ifndef _WIN32
+#ifdef HAVE_ETHER_HOSTTON
 /*
 /*
- * XXX - why was this included even on UNIX?
+ * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
+ * ether_hostton()?
  */
  */
-#ifdef __MINGW32__
-#include "IP6_misc.h"
-#endif
-
-#ifndef WIN32
-#ifdef HAVE_ETHER_HOSTTON
 #ifdef HAVE_NETINET_IF_ETHER_H
 struct mbuf;           /* Squelch compiler warnings on some platforms for */
 struct rtentry;                /* declarations in <net/if.h> */
 #include <net/if.h>    /* for "struct ifnet" in "struct arpcom" on Solaris */
 #include <netinet/if_ether.h>
 #endif /* HAVE_NETINET_IF_ETHER_H */
 #ifdef HAVE_NETINET_IF_ETHER_H
 struct mbuf;           /* Squelch compiler warnings on some platforms for */
 struct rtentry;                /* declarations in <net/if.h> */
 #include <net/if.h>    /* for "struct ifnet" in "struct arpcom" on Solaris */
 #include <netinet/if_ether.h>
 #endif /* HAVE_NETINET_IF_ETHER_H */
+#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
+#include <netinet/ether.h>
+#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
 #endif /* HAVE_ETHER_HOSTTON */
 #include <arpa/inet.h>
 #include <netdb.h>
 #endif /* HAVE_ETHER_HOSTTON */
 #include <arpa/inet.h>
 #include <netdb.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
 
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <memory.h>
+#include <string.h>
 #include <stdio.h>
 
 #include "pcap-int.h"
 
 #include "gencode.h"
 #include <stdio.h>
 
 #include "pcap-int.h"
 
 #include "gencode.h"
-#include <pcap-namedb.h>
+#include <pcap/namedb.h>
+#include "nametoaddr.h"
 
 #ifdef HAVE_OS_PROTO_H
 #include "os-proto.h"
 
 #ifdef HAVE_OS_PROTO_H
 #include "os-proto.h"
@@ -124,7 +151,7 @@ pcap_nametoaddrinfo(const char *name)
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;        /*not really*/
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;        /*not really*/
-       hints.ai_socktype = IPPROTO_TCP;        /*not really*/
+       hints.ai_protocol = IPPROTO_TCP;        /*not really*/
        error = getaddrinfo(name, NULL, &hints, &res);
        if (error)
                return NULL;
        error = getaddrinfo(name, NULL, &hints, &res);
        if (error)
                return NULL;
@@ -140,7 +167,7 @@ pcap_nametoaddrinfo(const char *name)
 bpf_u_int32
 pcap_nametonetaddr(const char *name)
 {
 bpf_u_int32
 pcap_nametonetaddr(const char *name)
 {
-#ifndef WIN32
+#ifndef _WIN32
        struct netent *np;
 
        if ((np = getnetbyname(name)) != NULL)
        struct netent *np;
 
        if ((np = getnetbyname(name)) != NULL)
@@ -150,6 +177,15 @@ pcap_nametonetaddr(const char *name)
 #else
        /*
         * There's no "getnetbyname()" on Windows.
 #else
        /*
         * There's no "getnetbyname()" on Windows.
+        *
+        * XXX - I guess we could use the BSD code to read
+        * C:\Windows\System32\drivers\etc/networks, assuming
+        * that's its home on all the versions of Windows
+        * we use, but that file probably just has the loopback
+        * network on 127/24 on 99 44/100% of Windows machines.
+        *
+        * (Heck, these days it probably just has that on 99 44/100%
+        * of *UN*X* machines.)
         */
        return 0;
 #endif
         */
        return 0;
 #endif
@@ -209,6 +245,52 @@ pcap_nametoport(const char *name, int *port, int *proto)
        return 0;
 }
 
        return 0;
 }
 
+/*
+ * Convert a string in the form PPP-PPP, where correspond to ports, to
+ * a starting and ending port in a port range.
+ * Return 0 on failure.
+ */
+int
+pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
+{
+       u_int p1, p2;
+       char *off, *cpy;
+       int save_proto;
+
+       if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
+               if ((cpy = strdup(name)) == NULL)
+                       return 0;
+
+               if ((off = strchr(cpy, '-')) == NULL) {
+                       free(cpy);
+                       return 0;
+               }
+
+               *off = '\0';
+
+               if (pcap_nametoport(cpy, port1, proto) == 0) {
+                       free(cpy);
+                       return 0;
+               }
+               save_proto = *proto;
+
+               if (pcap_nametoport(off + 1, port2, proto) == 0) {
+                       free(cpy);
+                       return 0;
+               }
+               free(cpy);
+
+               if (*proto != save_proto)
+                       *proto = PROTO_UNDEF;
+       } else {
+               *port1 = p1;
+               *port2 = p2;
+               *proto = PROTO_UNDEF;
+       }
+
+       return 1;
+}
+
 int
 pcap_nametoproto(const char *str)
 {
 int
 pcap_nametoproto(const char *str)
 {
@@ -224,12 +306,18 @@ pcap_nametoproto(const char *str)
 #include "ethertype.h"
 
 struct eproto {
 #include "ethertype.h"
 
 struct eproto {
-       char *s;
+       const char *s;
        u_short p;
 };
 
        u_short p;
 };
 
-/* Static data base of ether protocol types. */
-struct eproto eproto_db[] = {
+/*
+ * Static data base of ether protocol types.
+ * tcpdump used to import this, and it's declared as an export on
+ * Debian, at least, so make it a public symbol, even though we
+ * don't officially export it by declaring it in a header file.
+ * (Programs *should* do this themselves, as tcpdump now does.)
+ */
+PCAP_API_DEF struct eproto eproto_db[] = {
        { "pup", ETHERTYPE_PUP },
        { "xns", ETHERTYPE_NS },
        { "ip", ETHERTYPE_IP },
        { "pup", ETHERTYPE_PUP },
        { "xns", ETHERTYPE_NS },
        { "ip", ETHERTYPE_IP },
@@ -268,6 +356,30 @@ pcap_nametoeproto(const char *s)
        return PROTO_UNDEF;
 }
 
        return PROTO_UNDEF;
 }
 
+#include "llc.h"
+
+/* Static data base of LLC values. */
+static struct eproto llc_db[] = {
+       { "iso", LLCSAP_ISONS },
+       { "stp", LLCSAP_8021D },
+       { "ipx", LLCSAP_IPX },
+       { "netbeui", LLCSAP_NETBEUI },
+       { (char *)0, 0 }
+};
+
+int
+pcap_nametollc(const char *s)
+{
+       struct eproto *p = llc_db;
+
+       while (p->s != 0) {
+               if (strcmp(p->s, s) == 0)
+                       return p->p;
+               p += 1;
+       }
+       return PROTO_UNDEF;
+}
+
 /* Hex digit to integer. */
 static inline int
 xdtoi(c)
 /* Hex digit to integer. */
 static inline int
 xdtoi(c)
@@ -312,8 +424,8 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
 
        u_int node, area;
 
 
        u_int node, area;
 
-       if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
-               bpf_error("malformed decnet address '%s'", s);
+       if (sscanf(s, "%d.%d", &area, &node) != 2)
+               return(0);
 
        *addr = (area << AREASHIFT) & AREAMASK;
        *addr |= (node & NODEMASK);
 
        *addr = (area << AREASHIFT) & AREAMASK;
        *addr |= (node & NODEMASK);
@@ -322,7 +434,15 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
 }
 
 /*
 }
 
 /*
- * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
+ * Convert 's', which can have the one of the forms:
+ *
+ *     "xx:xx:xx:xx:xx:xx"
+ *     "xx.xx.xx.xx.xx.xx"
+ *     "xx-xx-xx-xx-xx-xx"
+ *     "xxxx.xxxx.xxxx"
+ *     "xxxxxxxxxxxx"
+ *
+ * (or various mixes of ':', '.', and '-') into a new
  * ethernet address.  Assumes 's' is well formed.
  */
 u_char *
  * ethernet address.  Assumes 's' is well formed.
  */
 u_char *
@@ -332,9 +452,11 @@ pcap_ether_aton(const char *s)
        register u_int d;
 
        e = ep = (u_char *)malloc(6);
        register u_int d;
 
        e = ep = (u_char *)malloc(6);
+       if (e == NULL)
+               return (NULL);
 
        while (*s) {
 
        while (*s) {
-               if (*s == ':')
+               if (*s == ':' || *s == '.' || *s == '-')
                        s += 1;
                d = xdtoi(*s++);
                if (isxdigit((unsigned char)*s)) {
                        s += 1;
                d = xdtoi(*s++);
                if (isxdigit((unsigned char)*s)) {
@@ -381,18 +503,13 @@ pcap_ether_hostton(const char *name)
 }
 #else
 
 }
 #else
 
-/*
- * XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files,
- * for those OS versions that don't declare it, rather than being declared
- * here?  That way, for example, we could declare it on FreeBSD 2.x (which
- * doesn't declare it), but not on FreeBSD 3.x (which declares it like
- * this) or FreeBSD 4.x (which declares it with its first argument as
- * "const char *", so no matter how we declare it here, it'll fail to
- * compile on one of 3.x or 4.x).
- */
-#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
-       !defined(_UNICOSMP)
-extern int ether_hostton(char *, struct ether_addr *);
+#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
+#ifndef HAVE_STRUCT_ETHER_ADDR
+struct ether_addr {
+       unsigned char ether_addr_octet[6];
+};
+#endif
+extern int ether_hostton(const char *, struct ether_addr *);
 #endif
 
 /* Use the os supplied routines */
 #endif
 
 /* Use the os supplied routines */
@@ -403,7 +520,7 @@ pcap_ether_hostton(const char *name)
        u_char a[6];
 
        ap = NULL;
        u_char a[6];
 
        ap = NULL;
-       if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) {
+       if (ether_hostton(name, (struct ether_addr *)a) == 0) {
                ap = (u_char *)malloc(6);
                if (ap != NULL)
                        memcpy((char *)ap, (char *)a, 6);
                ap = (u_char *)malloc(6);
                if (ap != NULL)
                        memcpy((char *)ap, (char *)a, 6);
@@ -412,23 +529,20 @@ pcap_ether_hostton(const char *name)
 }
 #endif
 
 }
 #endif
 
-u_short
-__pcap_nametodnaddr(const char *name)
+int
+__pcap_nametodnaddr(const char *name, u_short *res)
 {
 #ifdef DECNETLIB
        struct nodeent *getnodebyname();
        struct nodeent *nep;
 {
 #ifdef DECNETLIB
        struct nodeent *getnodebyname();
        struct nodeent *nep;
-       unsigned short res;
 
        nep = getnodebyname(name);
        if (nep == ((struct nodeent *)0))
 
        nep = getnodebyname(name);
        if (nep == ((struct nodeent *)0))
-               bpf_error("unknown decnet host name '%s'\n", name);
+               return(0);
 
 
-       memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
-       return(res);
+       memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
+       return(1);
 #else
 #else
-       bpf_error("decnet name support not included, '%s' cannot be translated\n",
-               name);
        return(0);
 #endif
 }
        return(0);
 #endif
 }