source: rtems-libbsd/freebsd/contrib/libpcap/nametoaddr.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

  • Update the file builder generator to handle generator specific cflags and includes. The tcpdump and libpcap have localised headers and need specific headers paths to see them. There are also module specific flags and these need to be passed to the lex and yacc generators.
  • Add the tcpdump support.
  • Property mode set to 100644
File size: 10.8 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 *
23 * Name to id translation routines used by the scanner.
24 * These functions are not time critical.
25 *
26 * $FreeBSD$
27 */
28
29#ifndef lint
30static const char rcsid[] _U_ =
31    "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.83 2008-02-06 10:21:30 guy Exp $ (LBL)";
32#endif
33
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
38#ifdef DECNETLIB
39#include <rtems/bsd/sys/types.h>
40#include <netdnet/dnetdb.h>
41#endif
42
43#ifdef WIN32
44#include <pcap-stdinc.h>
45
46#else /* WIN32 */
47
48#include <rtems/bsd/sys/param.h>
49#include <rtems/bsd/sys/types.h>                                /* concession to AIX */
50#include <sys/socket.h>
51#include <rtems/bsd/sys/time.h>
52
53#include <netinet/in.h>
54#endif /* WIN32 */
55
56#ifndef WIN32
57#ifdef HAVE_ETHER_HOSTTON
58/*
59 * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
60 * ether_hostton()?
61 */
62#ifdef HAVE_NETINET_IF_ETHER_H
63struct mbuf;            /* Squelch compiler warnings on some platforms for */
64struct rtentry;         /* declarations in <net/if.h> */
65#include <net/if.h>     /* for "struct ifnet" in "struct arpcom" on Solaris */
66#include <netinet/if_ether.h>
67#endif /* HAVE_NETINET_IF_ETHER_H */
68#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
69#include <netinet/ether.h>
70#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
71#endif /* HAVE_ETHER_HOSTTON */
72#include <arpa/inet.h>
73#include <netdb.h>
74#endif /* WIN32 */
75
76#include <ctype.h>
77#include <errno.h>
78#include <stdlib.h>
79#include <string.h>
80#include <stdio.h>
81
82#include "pcap-int.h"
83
84#include "gencode.h"
85#include <pcap/namedb.h>
86
87#ifdef HAVE_OS_PROTO_H
88#include "os-proto.h"
89#endif
90
91#ifndef NTOHL
92#define NTOHL(x) (x) = ntohl(x)
93#define NTOHS(x) (x) = ntohs(x)
94#endif
95
96static inline int xdtoi(int);
97
98/*
99 *  Convert host name to internet address.
100 *  Return 0 upon failure.
101 */
102bpf_u_int32 **
103pcap_nametoaddr(const char *name)
104{
105#ifndef h_addr
106        static bpf_u_int32 *hlist[2];
107#endif
108        bpf_u_int32 **p;
109        struct hostent *hp;
110
111        if ((hp = gethostbyname(name)) != NULL) {
112#ifndef h_addr
113                hlist[0] = (bpf_u_int32 *)hp->h_addr;
114                NTOHL(hp->h_addr);
115                return hlist;
116#else
117                for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
118                        NTOHL(**p);
119                return (bpf_u_int32 **)hp->h_addr_list;
120#endif
121        }
122        else
123                return 0;
124}
125
126#ifdef INET6
127struct addrinfo *
128pcap_nametoaddrinfo(const char *name)
129{
130        struct addrinfo hints, *res;
131        int error;
132
133        memset(&hints, 0, sizeof(hints));
134        hints.ai_family = PF_UNSPEC;
135        hints.ai_socktype = SOCK_STREAM;        /*not really*/
136        hints.ai_protocol = IPPROTO_TCP;        /*not really*/
137        error = getaddrinfo(name, NULL, &hints, &res);
138        if (error)
139                return NULL;
140        else
141                return res;
142}
143#endif /*INET6*/
144
145/*
146 *  Convert net name to internet address.
147 *  Return 0 upon failure.
148 */
149bpf_u_int32
150pcap_nametonetaddr(const char *name)
151{
152#ifndef WIN32
153        struct netent *np;
154
155        if ((np = getnetbyname(name)) != NULL)
156                return np->n_net;
157        else
158                return 0;
159#else
160        /*
161         * There's no "getnetbyname()" on Windows.
162         */
163        return 0;
164#endif
165}
166
167/*
168 * Convert a port name to its port and protocol numbers.
169 * We assume only TCP or UDP.
170 * Return 0 upon failure.
171 */
172int
173pcap_nametoport(const char *name, int *port, int *proto)
174{
175        struct servent *sp;
176        int tcp_port = -1;
177        int udp_port = -1;
178
179        /*
180         * We need to check /etc/services for ambiguous entries.
181         * If we find the ambiguous entry, and it has the
182         * same port number, change the proto to PROTO_UNDEF
183         * so both TCP and UDP will be checked.
184         */
185        sp = getservbyname(name, "tcp");
186        if (sp != NULL) tcp_port = ntohs(sp->s_port);
187        sp = getservbyname(name, "udp");
188        if (sp != NULL) udp_port = ntohs(sp->s_port);
189        if (tcp_port >= 0) {
190                *port = tcp_port;
191                *proto = IPPROTO_TCP;
192                if (udp_port >= 0) {
193                        if (udp_port == tcp_port)
194                                *proto = PROTO_UNDEF;
195#ifdef notdef
196                        else
197                                /* Can't handle ambiguous names that refer
198                                   to different port numbers. */
199                                warning("ambiguous port %s in /etc/services",
200                                        name);
201#endif
202                }
203                return 1;
204        }
205        if (udp_port >= 0) {
206                *port = udp_port;
207                *proto = IPPROTO_UDP;
208                return 1;
209        }
210#if defined(ultrix) || defined(__osf__)
211        /* Special hack in case NFS isn't in /etc/services */
212        if (strcmp(name, "nfs") == 0) {
213                *port = 2049;
214                *proto = PROTO_UNDEF;
215                return 1;
216        }
217#endif
218        return 0;
219}
220
221/*
222 * Convert a string in the form PPP-PPP, where correspond to ports, to
223 * a starting and ending port in a port range.
224 * Return 0 on failure.
225 */
226int
227pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
228{
229        u_int p1, p2;
230        char *off, *cpy;
231        int save_proto;
232
233        if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
234                if ((cpy = strdup(name)) == NULL)
235                        return 0;
236
237                if ((off = strchr(cpy, '-')) == NULL) {
238                        free(cpy);
239                        return 0;
240                }
241
242                *off = '\0';
243
244                if (pcap_nametoport(cpy, port1, proto) == 0) {
245                        free(cpy);
246                        return 0;
247                }
248                save_proto = *proto;
249
250                if (pcap_nametoport(off + 1, port2, proto) == 0) {
251                        free(cpy);
252                        return 0;
253                }
254                free(cpy);
255
256                if (*proto != save_proto)
257                        *proto = PROTO_UNDEF;
258        } else {
259                *port1 = p1;
260                *port2 = p2;
261                *proto = PROTO_UNDEF;
262        }
263
264        return 1;
265}
266
267int
268pcap_nametoproto(const char *str)
269{
270        struct protoent *p;
271
272        p = getprotobyname(str);
273        if (p != 0)
274                return p->p_proto;
275        else
276                return PROTO_UNDEF;
277}
278
279#include "ethertype.h"
280
281struct eproto {
282        const char *s;
283        u_short p;
284};
285
286/* Static data base of ether protocol types. */
287struct eproto eproto_db[] = {
288#if 0
289        /* The FreeBSD elf linker generates a request to copy this array
290         * (including its size) when you link with -lpcap.  In order to
291         * not bump the major version number of this libpcap.so, we need
292         * to ensure that the array stays the same size.  Since PUP is
293         * likely never seen in real life any more, it's the first to
294         * be sacrificed (in favor of ip6).
295         */
296        { "pup", ETHERTYPE_PUP },
297#endif
298        { "xns", ETHERTYPE_NS },
299        { "ip", ETHERTYPE_IP },
300#ifdef INET6
301        { "ip6", ETHERTYPE_IPV6 },
302#endif
303        { "arp", ETHERTYPE_ARP },
304        { "rarp", ETHERTYPE_REVARP },
305        { "sprite", ETHERTYPE_SPRITE },
306        { "mopdl", ETHERTYPE_MOPDL },
307        { "moprc", ETHERTYPE_MOPRC },
308        { "decnet", ETHERTYPE_DN },
309        { "lat", ETHERTYPE_LAT },
310        { "sca", ETHERTYPE_SCA },
311        { "lanbridge", ETHERTYPE_LANBRIDGE },
312        { "vexp", ETHERTYPE_VEXP },
313        { "vprod", ETHERTYPE_VPROD },
314        { "atalk", ETHERTYPE_ATALK },
315        { "atalkarp", ETHERTYPE_AARP },
316        { "loopback", ETHERTYPE_LOOPBACK },
317        { "decdts", ETHERTYPE_DECDTS },
318        { "decdns", ETHERTYPE_DECDNS },
319        { (char *)0, 0 }
320};
321
322int
323pcap_nametoeproto(const char *s)
324{
325        struct eproto *p = eproto_db;
326
327        while (p->s != 0) {
328                if (strcmp(p->s, s) == 0)
329                        return p->p;
330                p += 1;
331        }
332        return PROTO_UNDEF;
333}
334
335#include "llc.h"
336
337/* Static data base of LLC values. */
338static struct eproto llc_db[] = {
339        { "iso", LLCSAP_ISONS },
340        { "stp", LLCSAP_8021D },
341        { "ipx", LLCSAP_IPX },
342        { "netbeui", LLCSAP_NETBEUI },
343        { (char *)0, 0 }
344};
345
346int
347pcap_nametollc(const char *s)
348{
349        struct eproto *p = llc_db;
350
351        while (p->s != 0) {
352                if (strcmp(p->s, s) == 0)
353                        return p->p;
354                p += 1;
355        }
356        return PROTO_UNDEF;
357}
358
359/* Hex digit to integer. */
360static inline int
361xdtoi(c)
362        register int c;
363{
364        if (isdigit(c))
365                return c - '0';
366        else if (islower(c))
367                return c - 'a' + 10;
368        else
369                return c - 'A' + 10;
370}
371
372int
373__pcap_atoin(const char *s, bpf_u_int32 *addr)
374{
375        u_int n;
376        int len;
377
378        *addr = 0;
379        len = 0;
380        while (1) {
381                n = 0;
382                while (*s && *s != '.')
383                        n = n * 10 + *s++ - '0';
384                *addr <<= 8;
385                *addr |= n & 0xff;
386                len += 8;
387                if (*s == '\0')
388                        return len;
389                ++s;
390        }
391        /* NOTREACHED */
392}
393
394int
395__pcap_atodn(const char *s, bpf_u_int32 *addr)
396{
397#define AREASHIFT 10
398#define AREAMASK 0176000
399#define NODEMASK 01777
400
401        u_int node, area;
402
403        if (sscanf(s, "%d.%d", &area, &node) != 2)
404                bpf_error("malformed decnet address '%s'", s);
405
406        *addr = (area << AREASHIFT) & AREAMASK;
407        *addr |= (node & NODEMASK);
408
409        return(32);
410}
411
412/*
413 * Convert 's', which can have the one of the forms:
414 *
415 *      "xx:xx:xx:xx:xx:xx"
416 *      "xx.xx.xx.xx.xx.xx"
417 *      "xx-xx-xx-xx-xx-xx"
418 *      "xxxx.xxxx.xxxx"
419 *      "xxxxxxxxxxxx"
420 *
421 * (or various mixes of ':', '.', and '-') into a new
422 * ethernet address.  Assumes 's' is well formed.
423 */
424u_char *
425pcap_ether_aton(const char *s)
426{
427        register u_char *ep, *e;
428        register u_int d;
429
430        e = ep = (u_char *)malloc(6);
431
432        while (*s) {
433                if (*s == ':' || *s == '.' || *s == '-')
434                        s += 1;
435                d = xdtoi(*s++);
436                if (isxdigit((unsigned char)*s)) {
437                        d <<= 4;
438                        d |= xdtoi(*s++);
439                }
440                *ep++ = d;
441        }
442
443        return (e);
444}
445
446#ifndef HAVE_ETHER_HOSTTON
447/* Roll our own */
448u_char *
449pcap_ether_hostton(const char *name)
450{
451        register struct pcap_etherent *ep;
452        register u_char *ap;
453        static FILE *fp = NULL;
454        static int init = 0;
455
456        if (!init) {
457                fp = fopen(PCAP_ETHERS_FILE, "r");
458                ++init;
459                if (fp == NULL)
460                        return (NULL);
461        } else if (fp == NULL)
462                return (NULL);
463        else
464                rewind(fp);
465
466        while ((ep = pcap_next_etherent(fp)) != NULL) {
467                if (strcmp(ep->name, name) == 0) {
468                        ap = (u_char *)malloc(6);
469                        if (ap != NULL) {
470                                memcpy(ap, ep->addr, 6);
471                                return (ap);
472                        }
473                        break;
474                }
475        }
476        return (NULL);
477}
478#else
479
480#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
481#ifndef HAVE_STRUCT_ETHER_ADDR
482struct ether_addr {
483        unsigned char ether_addr_octet[6];
484};
485#endif
486extern int ether_hostton(const char *, struct ether_addr *);
487#endif
488
489/* Use the os supplied routines */
490u_char *
491pcap_ether_hostton(const char *name)
492{
493        register u_char *ap;
494        u_char a[6];
495
496        ap = NULL;
497        if (ether_hostton(name, (struct ether_addr *)a) == 0) {
498                ap = (u_char *)malloc(6);
499                if (ap != NULL)
500                        memcpy((char *)ap, (char *)a, 6);
501        }
502        return (ap);
503}
504#endif
505
506u_short
507__pcap_nametodnaddr(const char *name)
508{
509#ifdef  DECNETLIB
510        struct nodeent *getnodebyname();
511        struct nodeent *nep;
512        unsigned short res;
513
514        nep = getnodebyname(name);
515        if (nep == ((struct nodeent *)0))
516                bpf_error("unknown decnet host name '%s'\n", name);
517
518        memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
519        return(res);
520#else
521        bpf_error("decnet name support not included, '%s' cannot be translated\n",
522                name);
523        return(0);
524#endif
525}
Note: See TracBrowser for help on using the repository browser.