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

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 3d1e767 was 3d1e767, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/16 at 08:25:22

Directly use <sys/types.h> provided by Newlib

  • Property mode set to 100644
File size: 10.7 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 <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 <sys/types.h>                          /* concession to AIX */
50#include <sys/socket.h>
51#include <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.