]> git.saurik.com Git - apple/network_cmds.git/blob - pcap/nametoaddr.c
3ce8008ed80035b5cb6be822e6475c61113aa1df
[apple/network_cmds.git] / pcap / nametoaddr.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /* $OpenBSD: nametoaddr.c,v 1.5 1996/09/16 02:33:06 tholo Exp $ */
25
26 /*
27 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
28 * The Regents of the University of California. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that: (1) source code distributions
32 * retain the above copyright notice and this paragraph in its entirety, (2)
33 * distributions including binary code include the above copyright notice and
34 * this paragraph in its entirety in the documentation or other materials
35 * provided with the distribution, and (3) all advertising materials mentioning
36 * features or use of this software display the following acknowledgement:
37 * ``This product includes software developed by the University of California,
38 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
39 * the University nor the names of its contributors may be used to endorse
40 * or promote products derived from this software without specific prior
41 * written permission.
42 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
43 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
44 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
45 *
46 * Name to id translation routines used by the scanner.
47 * These functions are not time critical.
48 */
49
50 #ifndef lint
51 static char rcsid[] =
52 "@(#) Header: nametoaddr.c,v 1.38 96/06/17 02:42:50 leres Exp (LBL)";
53 #endif
54
55 #include <sys/param.h>
56 #include <sys/socket.h>
57
58 #if __STDC__
59 struct mbuf;
60 struct rtentry;
61 #endif
62
63 #include <net/if.h>
64 #include <netinet/in.h>
65 #include <netinet/if_ether.h>
66 #include <arpa/inet.h>
67
68 #include <ctype.h>
69 #include <errno.h>
70 #include <stdlib.h>
71 #include <memory.h>
72 #include <netdb.h>
73 #include <pcap.h>
74 #include <pcap-namedb.h>
75 #include <stdio.h>
76
77 #ifdef HAVE_OS_PROTO_H
78 #include "os-proto.h"
79 #endif
80
81 #include "pcap-int.h"
82 #include "gencode.h"
83
84 #ifndef NTOHL
85 #define NTOHL(x) (x) = ntohl(x)
86 #define NTOHS(x) (x) = ntohs(x)
87 #endif
88
89 static __inline int xdtoi(int);
90
91 /*
92 * Convert host name to internet address.
93 * Return 0 upon failure.
94 */
95 bpf_u_int32 **
96 pcap_nametoaddr(const char *name)
97 {
98 #ifndef h_addr
99 static bpf_u_int32 *hlist[2];
100 #endif
101 bpf_u_int32 **p;
102 struct hostent *hp;
103
104 if ((hp = gethostbyname(name)) != NULL) {
105 #ifndef h_addr
106 hlist[0] = (bpf_u_int32 *)hp->h_addr;
107 NTOHL(hp->h_addr);
108 return hlist;
109 #else
110 for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
111 NTOHL(**p);
112 return (bpf_u_int32 **)hp->h_addr_list;
113 #endif
114 }
115 else
116 return 0;
117 }
118
119 /*
120 * Convert net name to internet address.
121 * Return 0 upon failure.
122 */
123 bpf_u_int32
124 pcap_nametonetaddr(const char *name)
125 {
126 struct netent *np;
127
128 if ((np = getnetbyname(name)) != NULL)
129 return np->n_net;
130 else
131 return 0;
132 }
133
134 /*
135 * Convert a port name to its port and protocol numbers.
136 * We assume only TCP or UDP.
137 * Return 0 upon failure.
138 */
139 int
140 pcap_nametoport(const char *name, int *port, int *proto)
141 {
142 struct servent *sp;
143 char *other;
144
145 sp = getservbyname(name, (char *)0);
146 if (sp != NULL) {
147 NTOHS(sp->s_port);
148 *port = sp->s_port;
149 *proto = pcap_nametoproto(sp->s_proto);
150 /*
151 * We need to check /etc/services for ambiguous entries.
152 * If we find the ambiguous entry, and it has the
153 * same port number, change the proto to PROTO_UNDEF
154 * so both TCP and UDP will be checked.
155 */
156 if (*proto == IPPROTO_TCP)
157 other = "udp";
158 else
159 other = "tcp";
160
161 sp = getservbyname(name, other);
162 if (sp != 0) {
163 NTOHS(sp->s_port);
164 #ifdef notdef
165 if (*port != sp->s_port)
166 /* Can't handle ambiguous names that refer
167 to different port numbers. */
168 warning("ambiguous port %s in /etc/services",
169 name);
170 #endif
171 *proto = PROTO_UNDEF;
172 }
173 return 1;
174 }
175 #if defined(ultrix) || defined(__osf__)
176 /* Special hack in case NFS isn't in /etc/services */
177 if (strcmp(name, "nfs") == 0) {
178 *port = 2049;
179 *proto = PROTO_UNDEF;
180 return 1;
181 }
182 #endif
183 return 0;
184 }
185
186 int
187 pcap_nametoproto(const char *str)
188 {
189 struct protoent *p;
190
191 p = getprotobyname(str);
192 if (p != 0)
193 return p->p_proto;
194 else
195 return PROTO_UNDEF;
196 }
197
198 #include "ethertype.h"
199
200 struct eproto {
201 char *s;
202 u_short p;
203 };
204
205 /* Static data base of ether protocol types. */
206 struct eproto eproto_db[] = {
207 { "pup", ETHERTYPE_PUP },
208 { "xns", ETHERTYPE_NS },
209 { "ip", ETHERTYPE_IP },
210 { "arp", ETHERTYPE_ARP },
211 { "rarp", ETHERTYPE_REVARP },
212 { "sprite", ETHERTYPE_SPRITE },
213 { "mopdl", ETHERTYPE_MOPDL },
214 { "moprc", ETHERTYPE_MOPRC },
215 { "decnet", ETHERTYPE_DN },
216 { "lat", ETHERTYPE_LAT },
217 { "lanbridge", ETHERTYPE_LANBRIDGE },
218 { "vexp", ETHERTYPE_VEXP },
219 { "vprod", ETHERTYPE_VPROD },
220 { "atalk", ETHERTYPE_ATALK },
221 { "atalkarp", ETHERTYPE_AARP },
222 { "loopback", ETHERTYPE_LOOPBACK },
223 { "decdts", ETHERTYPE_DECDTS },
224 { "decdns", ETHERTYPE_DECDNS },
225 { (char *)0, 0 }
226 };
227
228 int
229 pcap_nametoeproto(const char *s)
230 {
231 struct eproto *p = eproto_db;
232
233 while (p->s != 0) {
234 if (strcmp(p->s, s) == 0)
235 return p->p;
236 p += 1;
237 }
238 return PROTO_UNDEF;
239 }
240
241 /* Hex digit to integer. */
242 static __inline int
243 xdtoi(c)
244 register int c;
245 {
246 if (isdigit(c))
247 return c - '0';
248 else if (islower(c))
249 return c - 'a' + 10;
250 else
251 return c - 'A' + 10;
252 }
253
254 bpf_u_int32
255 __pcap_atoin(const char *s)
256 {
257 bpf_u_int32 addr = 0;
258 u_int n;
259
260 while (1) {
261 n = 0;
262 while (*s && *s != '.')
263 n = n * 10 + *s++ - '0';
264 addr <<= 8;
265 addr |= n & 0xff;
266 if (*s == '\0')
267 return addr;
268 ++s;
269 }
270 /* NOTREACHED */
271 }
272
273 bpf_u_int32
274 __pcap_atodn(const char *s)
275 {
276 #define AREASHIFT 10
277 #define AREAMASK 0176000
278 #define NODEMASK 01777
279
280 bpf_u_int32 addr = 0;
281 u_int node, area;
282
283 if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
284 bpf_error("malformed decnet address '%s'", s);
285
286 addr = (area << AREASHIFT) & AREAMASK;
287 addr |= (node & NODEMASK);
288
289 return(addr);
290 }
291
292 /*
293 * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
294 * ethernet address. Assumes 's' is well formed.
295 */
296 u_char *
297 pcap_ether_aton(const char *s)
298 {
299 register u_char *ep, *e;
300 register u_int d;
301
302 e = ep = (u_char *)malloc(6);
303
304 while (*s) {
305 if (*s == ':')
306 s += 1;
307 d = xdtoi(*s++);
308 if (isxdigit(*s)) {
309 d <<= 4;
310 d |= xdtoi(*s++);
311 }
312 *ep++ = d;
313 }
314
315 return (e);
316 }
317
318 #ifndef HAVE_ETHER_HOSTTON
319 /* Roll our own */
320 u_char *
321 pcap_ether_hostton(const char *name)
322 {
323 register struct pcap_etherent *ep;
324 register u_char *ap;
325 static FILE *fp = NULL;
326 static init = 0;
327
328 if (!init) {
329 fp = fopen(PCAP_ETHERS_FILE, "r");
330 ++init;
331 if (fp == NULL)
332 return (NULL);
333 } else if (fp == NULL)
334 return (NULL);
335 else
336 rewind(fp);
337
338 while ((ep = pcap_next_etherent(fp)) != NULL) {
339 if (strcmp(ep->name, name) == 0) {
340 ap = (u_char *)malloc(6);
341 if (ap != NULL) {
342 memcpy(ap, ep->addr, 6);
343 return (ap);
344 }
345 break;
346 }
347 }
348 return (NULL);
349 }
350 #else
351
352 #ifndef sgi
353 extern int ether_hostton(char *, struct ether_addr *);
354 #endif
355
356 /* Use the os supplied routines */
357 u_char *
358 pcap_ether_hostton(const char *name)
359 {
360 register u_char *ap;
361 u_char a[6];
362
363 ap = NULL;
364 if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) {
365 ap = (u_char *)malloc(6);
366 if (ap != NULL)
367 memcpy(ap, a, 6);
368 }
369 return (ap);
370 }
371 #endif
372
373 u_short
374 __pcap_nametodnaddr(const char *name)
375 {
376 #ifdef DECNETLIB
377 struct nodeent *getnodebyname();
378 struct nodeent *nep;
379 unsigned short res;
380
381 nep = getnodebyname(name);
382 if (nep == ((struct nodeent *)0))
383 bpf_error("unknown decnet host name '%s'\n", name);
384
385 memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
386 return(res);
387 #else
388 bpf_error("decnet name support not included, '%s' cannot be translated\n",
389 name);
390 #ifdef lint
391 return 0;
392 #endif
393 #endif
394 }