]> The Tcpdump Group git mirrors - libpcap/blob - nametoaddr.c
c69c36dddbbd5629cca12d1a9c1b723abe5da070
[libpcap] / nametoaddr.c
1 /*
2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * Name to id translation routines used by the scanner.
22 * These functions are not time critical.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #ifdef DECNETLIB
30 #include <sys/types.h>
31 #include <netdnet/dnetdb.h>
32 #endif
33
34 #ifdef _WIN32
35 #include <winsock2.h>
36 #include <ws2tcpip.h>
37
38 #ifdef INET6
39 /*
40 * To quote the MSDN page for getaddrinfo() at
41 *
42 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
43 *
44 * "Support for getaddrinfo on Windows 2000 and older versions
45 * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
46 * later. To execute an application that uses this function on earlier
47 * versions of Windows, then you need to include the Ws2tcpip.h and
48 * Wspiapi.h files. When the Wspiapi.h include file is added, the
49 * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
50 * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
51 * function is implemented in such a way that if the Ws2_32.dll or the
52 * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
53 * Preview for Windows 2000) does not include getaddrinfo, then a
54 * version of getaddrinfo is implemented inline based on code in the
55 * Wspiapi.h header file. This inline code will be used on older Windows
56 * platforms that do not natively support the getaddrinfo function."
57 *
58 * We use getaddrinfo(), so we include Wspiapi.h here.
59 */
60 #include <wspiapi.h>
61 #endif /* INET6 */
62 #else /* _WIN32 */
63 #include <sys/param.h>
64 #include <sys/types.h>
65 #include <sys/socket.h>
66 #include <sys/time.h>
67
68 #include <netinet/in.h>
69
70 #ifdef HAVE_ETHER_HOSTTON
71 #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
72 /*
73 * OK, just include <net/ethernet.h>.
74 */
75 #include <net/ethernet.h>
76 #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
77 /*
78 * OK, just include <netinet/ether.h>
79 */
80 #include <netinet/ether.h>
81 #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
82 /*
83 * OK, just include <sys/ethernet.h>
84 */
85 #include <sys/ethernet.h>
86 #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
87 /*
88 * OK, just include <arpa/inet.h>
89 */
90 #include <arpa/inet.h>
91 #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
92 /*
93 * OK, include <netinet/if_ether.h>, after all the other stuff we
94 * need to include or define for its benefit.
95 */
96 #define NEED_NETINET_IF_ETHER_H
97 #else
98 /*
99 * We'll have to declare it ourselves.
100 * If <netinet/if_ether.h> defines struct ether_addr, include
101 * it. Otherwise, define it ourselves.
102 */
103 #ifdef HAVE_STRUCT_ETHER_ADDR
104 #define NEED_NETINET_IF_ETHER_H
105 #else /* HAVE_STRUCT_ETHER_ADDR */
106 struct ether_addr {
107 unsigned char ether_addr_octet[6];
108 };
109 #endif /* HAVE_STRUCT_ETHER_ADDR */
110 #endif /* what declares ether_hostton() */
111
112 #ifdef NEED_NETINET_IF_ETHER_H
113 #include <net/if.h> /* Needed on some platforms */
114 #include <netinet/in.h> /* Needed on some platforms */
115 #include <netinet/if_ether.h>
116 #endif /* NEED_NETINET_IF_ETHER_H */
117
118 #ifndef HAVE_DECL_ETHER_HOSTTON
119 /*
120 * No header declares it, so declare it ourselves.
121 */
122 extern int ether_hostton(const char *, struct ether_addr *);
123 #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
124 #endif /* HAVE_ETHER_HOSTTON */
125
126 #include <arpa/inet.h>
127 #include <netdb.h>
128 #endif /* _WIN32 */
129
130 #include <ctype.h>
131 #include <errno.h>
132 #include <stdlib.h>
133 #include <string.h>
134 #include <stdio.h>
135
136 #include "pcap-int.h"
137
138 #include "gencode.h"
139 #include <pcap/namedb.h>
140 #include "nametoaddr.h"
141
142 #ifdef HAVE_OS_PROTO_H
143 #include "os-proto.h"
144 #endif
145
146 #ifndef NTOHL
147 #define NTOHL(x) (x) = ntohl(x)
148 #define NTOHS(x) (x) = ntohs(x)
149 #endif
150
151 static inline int xdtoi(int);
152
153 /*
154 * Convert host name to internet address.
155 * Return 0 upon failure.
156 * XXX - not thread-safe; don't use it inside libpcap.
157 */
158 bpf_u_int32 **
159 pcap_nametoaddr(const char *name)
160 {
161 #ifndef h_addr
162 static bpf_u_int32 *hlist[2];
163 #endif
164 bpf_u_int32 **p;
165 struct hostent *hp;
166
167 if ((hp = gethostbyname(name)) != NULL) {
168 #ifndef h_addr
169 hlist[0] = (bpf_u_int32 *)hp->h_addr;
170 NTOHL(hp->h_addr);
171 return hlist;
172 #else
173 for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
174 NTOHL(**p);
175 return (bpf_u_int32 **)hp->h_addr_list;
176 #endif
177 }
178 else
179 return 0;
180 }
181
182 struct addrinfo *
183 pcap_nametoaddrinfo(const char *name)
184 {
185 struct addrinfo hints, *res;
186 int error;
187
188 memset(&hints, 0, sizeof(hints));
189 hints.ai_family = PF_UNSPEC;
190 hints.ai_socktype = SOCK_STREAM; /*not really*/
191 hints.ai_protocol = IPPROTO_TCP; /*not really*/
192 error = getaddrinfo(name, NULL, &hints, &res);
193 if (error)
194 return NULL;
195 else
196 return res;
197 }
198
199 /*
200 * Convert net name to internet address.
201 * Return 0 upon failure.
202 * XXX - not guaranteed to be thread-safe! See below for platforms
203 * on which it is thread-safe and on which it isn't.
204 */
205 bpf_u_int32
206 pcap_nametonetaddr(const char *name)
207 {
208 #ifdef _WIN32
209 /*
210 * There's no "getnetbyname()" on Windows.
211 *
212 * XXX - I guess we could use the BSD code to read
213 * C:\Windows\System32\drivers\etc/networks, assuming
214 * that's its home on all the versions of Windows
215 * we use, but that file probably just has the loopback
216 * network on 127/24 on 99 44/100% of Windows machines.
217 *
218 * (Heck, these days it probably just has that on 99 44/100%
219 * of *UN*X* machines.)
220 */
221 return 0;
222 #else
223 /*
224 * UN*X.
225 */
226 struct netent *np;
227 #if defined(HAVE_LINUX_GETNETBYNAME_R)
228 /*
229 * We have Linux's reentrant getnetbyname_r().
230 */
231 struct netent result_buf;
232 char buf[1024]; /* arbitrary size */
233 int h_errnoval;
234 int err;
235
236 err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
237 &h_errnoval);
238 if (err != 0) {
239 /*
240 * XXX - dynamically allocate the buffer, and make it
241 * bigger if we get ERANGE back?
242 */
243 return 0;
244 }
245 #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
246 /*
247 * We have Solaris's and IRIX's reentrant getnetbyname_r().
248 */
249 struct netent result_buf;
250 char buf[1024]; /* arbitrary size */
251
252 np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
253 #elif defined(HAVE_AIX_GETNETBYNAME_R)
254 /*
255 * We have AIX's reentrant getnetbyname_r().
256 */
257 struct netent result_buf;
258 struct netent_data net_data;
259
260 if (getnetbyname_r(name, &result_buf, &net_data) == -1)
261 np = NULL;
262 else
263 np = &result_buf;
264 #else
265 /*
266 * We don't have any getnetbyname_r(); either we have a
267 * getnetbyname() that uses thread-specific data, in which
268 * case we're thread-safe (sufficiently recent FreeBSD,
269 * sufficiently recent Darwin-based OS, sufficiently recent
270 * HP-UX, sufficiently recent Tru64 UNIX), or we have the
271 * traditional getnetbyname() (everything else, including
272 * current NetBSD and OpenBSD), in which case we're not
273 * thread-safe.
274 */
275 np = getnetbyname(name);
276 #endif
277 if (np != NULL)
278 return np->n_net;
279 else
280 return 0;
281 #endif /* _WIN32 */
282 }
283
284 /*
285 * Convert a port name to its port and protocol numbers.
286 * We assume only TCP or UDP.
287 * Return 0 upon failure.
288 */
289 int
290 pcap_nametoport(const char *name, int *port, int *proto)
291 {
292 struct addrinfo hints, *res, *ai;
293 int error;
294 struct sockaddr_in *in4;
295 #ifdef INET6
296 struct sockaddr_in6 *in6;
297 #endif
298 int tcp_port = -1;
299 int udp_port = -1;
300
301 /*
302 * We check for both TCP and UDP in case there are
303 * ambiguous entries.
304 */
305 memset(&hints, 0, sizeof(hints));
306 hints.ai_family = PF_UNSPEC;
307 hints.ai_socktype = SOCK_STREAM;
308 hints.ai_protocol = IPPROTO_TCP;
309 error = getaddrinfo(NULL, name, &hints, &res);
310 if (error != 0) {
311 if (error != EAI_NONAME) {
312 /*
313 * This is a real error, not just "there's
314 * no such service name".
315 * XXX - this doesn't return an error string.
316 */
317 return 0;
318 }
319 } else {
320 /*
321 * OK, we found it. Did it find anything?
322 */
323 for (ai = res; ai != NULL; ai = ai->ai_next) {
324 /*
325 * Does it have an address?
326 */
327 if (ai->ai_addr != NULL) {
328 /*
329 * Yes. Get a port number; we're done.
330 */
331 if (ai->ai_addr->sa_family == AF_INET) {
332 in4 = (struct sockaddr_in *)ai->ai_addr;
333 tcp_port = ntohs(in4->sin_port);
334 break;
335 }
336 #ifdef INET6
337 if (ai->ai_addr->sa_family == AF_INET6) {
338 in6 = (struct sockaddr_in6 *)ai->ai_addr;
339 tcp_port = ntohs(in6->sin6_port);
340 break;
341 }
342 #endif
343 }
344 }
345 freeaddrinfo(res);
346 }
347
348 memset(&hints, 0, sizeof(hints));
349 hints.ai_family = PF_UNSPEC;
350 hints.ai_socktype = SOCK_DGRAM;
351 hints.ai_protocol = IPPROTO_UDP;
352 error = getaddrinfo(NULL, name, &hints, &res);
353 if (error != 0) {
354 if (error != EAI_NONAME) {
355 /*
356 * This is a real error, not just "there's
357 * no such service name".
358 * XXX - this doesn't return an error string.
359 */
360 return 0;
361 }
362 } else {
363 /*
364 * OK, we found it. Did it find anything?
365 */
366 for (ai = res; ai != NULL; ai = ai->ai_next) {
367 /*
368 * Does it have an address?
369 */
370 if (ai->ai_addr != NULL) {
371 /*
372 * Yes. Get a port number; we're done.
373 */
374 if (ai->ai_addr->sa_family == AF_INET) {
375 in4 = (struct sockaddr_in *)ai->ai_addr;
376 udp_port = ntohs(in4->sin_port);
377 break;
378 }
379 #ifdef INET6
380 if (ai->ai_addr->sa_family == AF_INET6) {
381 in6 = (struct sockaddr_in6 *)ai->ai_addr;
382 udp_port = ntohs(in6->sin6_port);
383 break;
384 }
385 #endif
386 }
387 }
388 freeaddrinfo(res);
389 }
390
391 /*
392 * We need to check /etc/services for ambiguous entries.
393 * If we find an ambiguous entry, and it has the
394 * same port number, change the proto to PROTO_UNDEF
395 * so both TCP and UDP will be checked.
396 */
397 if (tcp_port >= 0) {
398 *port = tcp_port;
399 *proto = IPPROTO_TCP;
400 if (udp_port >= 0) {
401 if (udp_port == tcp_port)
402 *proto = PROTO_UNDEF;
403 #ifdef notdef
404 else
405 /* Can't handle ambiguous names that refer
406 to different port numbers. */
407 warning("ambiguous port %s in /etc/services",
408 name);
409 #endif
410 }
411 return 1;
412 }
413 if (udp_port >= 0) {
414 *port = udp_port;
415 *proto = IPPROTO_UDP;
416 return 1;
417 }
418 #if defined(ultrix) || defined(__osf__)
419 /* Special hack in case NFS isn't in /etc/services */
420 if (strcmp(name, "nfs") == 0) {
421 *port = 2049;
422 *proto = PROTO_UNDEF;
423 return 1;
424 }
425 #endif
426 return 0;
427 }
428
429 /*
430 * Convert a string in the form PPP-PPP, where correspond to ports, to
431 * a starting and ending port in a port range.
432 * Return 0 on failure.
433 */
434 int
435 pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
436 {
437 u_int p1, p2;
438 char *off, *cpy;
439 int save_proto;
440
441 if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
442 if ((cpy = strdup(name)) == NULL)
443 return 0;
444
445 if ((off = strchr(cpy, '-')) == NULL) {
446 free(cpy);
447 return 0;
448 }
449
450 *off = '\0';
451
452 if (pcap_nametoport(cpy, port1, proto) == 0) {
453 free(cpy);
454 return 0;
455 }
456 save_proto = *proto;
457
458 if (pcap_nametoport(off + 1, port2, proto) == 0) {
459 free(cpy);
460 return 0;
461 }
462 free(cpy);
463
464 if (*proto != save_proto)
465 *proto = PROTO_UNDEF;
466 } else {
467 *port1 = p1;
468 *port2 = p2;
469 *proto = PROTO_UNDEF;
470 }
471
472 return 1;
473 }
474
475 /*
476 * XXX - not guaranteed to be thread-safe! See below for platforms
477 * on which it is thread-safe and on which it isn't.
478 */
479 int
480 pcap_nametoproto(const char *str)
481 {
482 struct protoent *p;
483 #if defined(HAVE_LINUX_GETNETBYNAME_R)
484 /*
485 * We have Linux's reentrant getprotobyname_r().
486 */
487 struct protoent result_buf;
488 char buf[1024]; /* arbitrary size */
489 int err;
490
491 err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
492 if (err != 0) {
493 /*
494 * XXX - dynamically allocate the buffer, and make it
495 * bigger if we get ERANGE back?
496 */
497 return 0;
498 }
499 #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
500 /*
501 * We have Solaris's and IRIX's reentrant getprotobyname_r().
502 */
503 struct protoent result_buf;
504 char buf[1024]; /* arbitrary size */
505
506 p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
507 #elif defined(HAVE_AIX_GETNETBYNAME_R)
508 /*
509 * We have AIX's reentrant getprotobyname_r().
510 */
511 struct protoent result_buf;
512 struct protoent_data proto_data;
513
514 if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
515 p = NULL;
516 else
517 p = &result_buf;
518 #else
519 /*
520 * We don't have any getprotobyname_r(); either we have a
521 * getprotobyname() that uses thread-specific data, in which
522 * case we're thread-safe (sufficiently recent FreeBSD,
523 * sufficiently recent Darwin-based OS, sufficiently recent
524 * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
525 * the traditional getprotobyname() (everything else, including
526 * current NetBSD and OpenBSD), in which case we're not
527 * thread-safe.
528 */
529 p = getprotobyname(str);
530 #endif
531 if (p != 0)
532 return p->p_proto;
533 else
534 return PROTO_UNDEF;
535 }
536
537 #include "ethertype.h"
538
539 struct eproto {
540 const char *s;
541 u_short p;
542 };
543
544 /*
545 * Static data base of ether protocol types.
546 * tcpdump used to import this, and it's declared as an export on
547 * Debian, at least, so make it a public symbol, even though we
548 * don't officially export it by declaring it in a header file.
549 * (Programs *should* do this themselves, as tcpdump now does.)
550 */
551 PCAP_API_DEF struct eproto eproto_db[] = {
552 { "pup", ETHERTYPE_PUP },
553 { "xns", ETHERTYPE_NS },
554 { "ip", ETHERTYPE_IP },
555 #ifdef INET6
556 { "ip6", ETHERTYPE_IPV6 },
557 #endif
558 { "arp", ETHERTYPE_ARP },
559 { "rarp", ETHERTYPE_REVARP },
560 { "sprite", ETHERTYPE_SPRITE },
561 { "mopdl", ETHERTYPE_MOPDL },
562 { "moprc", ETHERTYPE_MOPRC },
563 { "decnet", ETHERTYPE_DN },
564 { "lat", ETHERTYPE_LAT },
565 { "sca", ETHERTYPE_SCA },
566 { "lanbridge", ETHERTYPE_LANBRIDGE },
567 { "vexp", ETHERTYPE_VEXP },
568 { "vprod", ETHERTYPE_VPROD },
569 { "atalk", ETHERTYPE_ATALK },
570 { "atalkarp", ETHERTYPE_AARP },
571 { "loopback", ETHERTYPE_LOOPBACK },
572 { "decdts", ETHERTYPE_DECDTS },
573 { "decdns", ETHERTYPE_DECDNS },
574 { (char *)0, 0 }
575 };
576
577 int
578 pcap_nametoeproto(const char *s)
579 {
580 struct eproto *p = eproto_db;
581
582 while (p->s != 0) {
583 if (strcmp(p->s, s) == 0)
584 return p->p;
585 p += 1;
586 }
587 return PROTO_UNDEF;
588 }
589
590 #include "llc.h"
591
592 /* Static data base of LLC values. */
593 static struct eproto llc_db[] = {
594 { "iso", LLCSAP_ISONS },
595 { "stp", LLCSAP_8021D },
596 { "ipx", LLCSAP_IPX },
597 { "netbeui", LLCSAP_NETBEUI },
598 { (char *)0, 0 }
599 };
600
601 int
602 pcap_nametollc(const char *s)
603 {
604 struct eproto *p = llc_db;
605
606 while (p->s != 0) {
607 if (strcmp(p->s, s) == 0)
608 return p->p;
609 p += 1;
610 }
611 return PROTO_UNDEF;
612 }
613
614 /* Hex digit to integer. */
615 static inline int
616 xdtoi(c)
617 register int c;
618 {
619 if (isdigit(c))
620 return c - '0';
621 else if (islower(c))
622 return c - 'a' + 10;
623 else
624 return c - 'A' + 10;
625 }
626
627 int
628 __pcap_atoin(const char *s, bpf_u_int32 *addr)
629 {
630 u_int n;
631 int len;
632
633 *addr = 0;
634 len = 0;
635 while (1) {
636 n = 0;
637 while (*s && *s != '.')
638 n = n * 10 + *s++ - '0';
639 *addr <<= 8;
640 *addr |= n & 0xff;
641 len += 8;
642 if (*s == '\0')
643 return len;
644 ++s;
645 }
646 /* NOTREACHED */
647 }
648
649 int
650 __pcap_atodn(const char *s, bpf_u_int32 *addr)
651 {
652 #define AREASHIFT 10
653 #define AREAMASK 0176000
654 #define NODEMASK 01777
655
656 u_int node, area;
657
658 if (sscanf(s, "%d.%d", &area, &node) != 2)
659 return(0);
660
661 *addr = (area << AREASHIFT) & AREAMASK;
662 *addr |= (node & NODEMASK);
663
664 return(32);
665 }
666
667 /*
668 * Convert 's', which can have the one of the forms:
669 *
670 * "xx:xx:xx:xx:xx:xx"
671 * "xx.xx.xx.xx.xx.xx"
672 * "xx-xx-xx-xx-xx-xx"
673 * "xxxx.xxxx.xxxx"
674 * "xxxxxxxxxxxx"
675 *
676 * (or various mixes of ':', '.', and '-') into a new
677 * ethernet address. Assumes 's' is well formed.
678 */
679 u_char *
680 pcap_ether_aton(const char *s)
681 {
682 register u_char *ep, *e;
683 register u_int d;
684
685 e = ep = (u_char *)malloc(6);
686 if (e == NULL)
687 return (NULL);
688
689 while (*s) {
690 if (*s == ':' || *s == '.' || *s == '-')
691 s += 1;
692 d = xdtoi(*s++);
693 if (isxdigit((unsigned char)*s)) {
694 d <<= 4;
695 d |= xdtoi(*s++);
696 }
697 *ep++ = d;
698 }
699
700 return (e);
701 }
702
703 #ifndef HAVE_ETHER_HOSTTON
704 /*
705 * Roll our own.
706 * XXX - not thread-safe, because pcap_next_etherent() isn't thread-
707 * safe! Needs a mutex or a thread-safe pcap_next_etherent().
708 */
709 u_char *
710 pcap_ether_hostton(const char *name)
711 {
712 register struct pcap_etherent *ep;
713 register u_char *ap;
714 static FILE *fp = NULL;
715 static int init = 0;
716
717 if (!init) {
718 fp = fopen(PCAP_ETHERS_FILE, "r");
719 ++init;
720 if (fp == NULL)
721 return (NULL);
722 } else if (fp == NULL)
723 return (NULL);
724 else
725 rewind(fp);
726
727 while ((ep = pcap_next_etherent(fp)) != NULL) {
728 if (strcmp(ep->name, name) == 0) {
729 ap = (u_char *)malloc(6);
730 if (ap != NULL) {
731 memcpy(ap, ep->addr, 6);
732 return (ap);
733 }
734 break;
735 }
736 }
737 return (NULL);
738 }
739 #else
740 /*
741 * Use the OS-supplied routine.
742 * This *should* be thread-safe; the API doesn't have a static buffer.
743 */
744 u_char *
745 pcap_ether_hostton(const char *name)
746 {
747 register u_char *ap;
748 u_char a[6];
749
750 ap = NULL;
751 if (ether_hostton(name, (struct ether_addr *)a) == 0) {
752 ap = (u_char *)malloc(6);
753 if (ap != NULL)
754 memcpy((char *)ap, (char *)a, 6);
755 }
756 return (ap);
757 }
758 #endif
759
760 /*
761 * XXX - not guaranteed to be thread-safe!
762 */
763 int
764 __pcap_nametodnaddr(const char *name, u_short *res)
765 {
766 #ifdef DECNETLIB
767 struct nodeent *getnodebyname();
768 struct nodeent *nep;
769
770 nep = getnodebyname(name);
771 if (nep == ((struct nodeent *)0))
772 return(0);
773
774 memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
775 return(1);
776 #else
777 return(0);
778 #endif
779 }