chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / sunrpc / rpcinfo.c
1 /*
2  * Copyright (C) 1986, Sun Microsystems, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  *       copyright notice, this list of conditions and the following
12  *       disclaimer in the documentation and/or other materials
13  *       provided with the distribution.
14  *     * Neither the name of Sun Microsystems, Inc. nor the names of its
15  *       contributors may be used to endorse or promote products derived
16  *       from this software without specific prior written permission.
17  *
18  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 /*
33  * rpcinfo: ping a particular rpc program
34  *     or dump the portmapper
35  */
36
37 #include <getopt.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <rpc/rpc.h>
41 #include <stdio.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45 #include <netdb.h>
46 #include <rpc/pmap_prot.h>
47 #include <rpc/pmap_clnt.h>
48 #include <signal.h>
49 #include <ctype.h>
50 #include <locale.h>
51 #include <libintl.h>
52
53 #include "../version.h"
54 #define PACKAGE _libc_intl_domainname
55
56 #define MAXHOSTLEN 256
57
58 #define MIN_VERS        ((u_long) 0)
59 #define MAX_VERS        ((u_long) 4294967295UL)
60
61 static void udpping (u_short portflag, int argc, char **argv);
62 static void tcpping (u_short portflag, int argc, char **argv);
63 static int pstatus (CLIENT *client, u_long prognum, u_long vers);
64 static void pmapdump (int argc, char **argv);
65 static bool_t reply_proc (void *res, struct sockaddr_in *who);
66 static void brdcst (int argc, char **argv) __attribute__ ((noreturn));
67 static void deletereg (int argc, char **argv);
68 static void usage (FILE *stream);
69 static void print_version (void);
70 static u_long getprognum (char *arg);
71 static u_long getvers (char *arg);
72 static void get_inet_address (struct sockaddr_in *addr, char *host);
73
74 /*
75  * Functions to be performed.
76  */
77 #define NONE            0       /* no function */
78 #define PMAPDUMP        1       /* dump portmapper registrations */
79 #define TCPPING         2       /* ping TCP service */
80 #define UDPPING         3       /* ping UDP service */
81 #define BRDCST          4       /* ping broadcast UDP service */
82 #define DELETES         5       /* delete registration for the service */
83
84 int
85 main (int argc, char **argv)
86 {
87   register int c;
88   int errflg;
89   int function;
90   u_short portnum;
91   static const struct option long_options[] = {
92     { "help", no_argument, NULL, 'H' },
93     { "version", no_argument, NULL, 'V' },
94     { NULL, 0, NULL, 0 }
95   };
96
97   setlocale (LC_ALL, "");
98   textdomain (_libc_intl_domainname);
99
100   function = NONE;
101   portnum = 0;
102   errflg = 0;
103   while ((c = getopt_long (argc, argv, "ptubdn:", long_options, NULL)) != -1)
104     {
105       switch (c)
106         {
107
108         case 'p':
109           if (function != NONE)
110             errflg = 1;
111           else
112             function = PMAPDUMP;
113           break;
114
115         case 't':
116           if (function != NONE)
117             errflg = 1;
118           else
119             function = TCPPING;
120           break;
121
122         case 'u':
123           if (function != NONE)
124             errflg = 1;
125           else
126             function = UDPPING;
127           break;
128
129         case 'b':
130           if (function != NONE)
131             errflg = 1;
132           else
133             function = BRDCST;
134           break;
135
136         case 'n':
137           portnum = (u_short) atoi (optarg);    /* hope we don't get bogus # */
138           break;
139
140         case 'd':
141           if (function != NONE)
142             errflg = 1;
143           else
144             function = DELETES;
145           break;
146
147         case 'H':
148           usage (stdout);
149           return 0;
150
151         case 'V':
152           print_version ();
153           return 0;
154
155         case '?':
156           errflg = 1;
157         }
158     }
159
160   if (errflg || function == NONE)
161     {
162       usage (stderr);
163       return 1;
164     }
165
166   switch (function)
167     {
168
169     case PMAPDUMP:
170       if (portnum != 0)
171         {
172           usage (stderr);
173           return 1;
174         }
175       pmapdump (argc - optind, argv + optind);
176       break;
177
178     case UDPPING:
179       udpping (portnum, argc - optind, argv + optind);
180       break;
181
182     case TCPPING:
183       tcpping (portnum, argc - optind, argv + optind);
184       break;
185
186     case BRDCST:
187       if (portnum != 0)
188         {
189           usage (stderr);
190           return 1;
191         }
192       brdcst (argc - optind, argv + optind);
193       break;
194
195     case DELETES:
196       deletereg (argc - optind, argv + optind);
197       break;
198     }
199
200   return 0;
201 }
202
203 static void
204 udpping (portnum, argc, argv)
205      u_short portnum;
206      int argc;
207      char **argv;
208 {
209   struct timeval to;
210   struct sockaddr_in addr;
211   enum clnt_stat rpc_stat;
212   CLIENT *client;
213   u_long prognum, vers, minvers, maxvers;
214   int sock = RPC_ANYSOCK;
215   struct rpc_err rpcerr;
216   int failure;
217
218   if (argc < 2 || argc > 3)
219     {
220       usage (stderr);
221       exit (1);
222     }
223   prognum = getprognum (argv[1]);
224   get_inet_address (&addr, argv[0]);
225   /* Open the socket here so it will survive calls to clnt_destroy */
226   sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
227   if (sock < 0)
228     {
229       perror ("rpcinfo: socket");
230       exit (1);
231     }
232   failure = 0;
233   if (argc == 2)
234     {
235       /*
236        * A call to version 0 should fail with a program/version
237        * mismatch, and give us the range of versions supported.
238        */
239       addr.sin_port = htons (portnum);
240       to.tv_sec = 5;
241       to.tv_usec = 0;
242       if ((client = clntudp_create (&addr, prognum, (u_long) 0,
243                                     to, &sock)) == NULL)
244         {
245           clnt_pcreateerror ("rpcinfo");
246           printf (_("program %lu is not available\n"), prognum);
247           exit (1);
248         }
249       to.tv_sec = 10;
250       to.tv_usec = 0;
251       rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
252                             (char *) NULL, (xdrproc_t) xdr_void,
253                             (char *) NULL, to);
254       if (rpc_stat == RPC_PROGVERSMISMATCH)
255         {
256           clnt_geterr (client, &rpcerr);
257           minvers = rpcerr.re_vers.low;
258           maxvers = rpcerr.re_vers.high;
259         }
260       else if (rpc_stat == RPC_SUCCESS)
261         {
262           /*
263            * Oh dear, it DOES support version 0.
264            * Let's try version MAX_VERS.
265            */
266           addr.sin_port = htons (portnum);
267           to.tv_sec = 5;
268           to.tv_usec = 0;
269           if ((client = clntudp_create (&addr, prognum, MAX_VERS,
270                                         to, &sock)) == NULL)
271             {
272               clnt_pcreateerror ("rpcinfo");
273               printf (_("program %lu version %lu is not available\n"),
274                       prognum, MAX_VERS);
275               exit (1);
276             }
277           to.tv_sec = 10;
278           to.tv_usec = 0;
279           rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
280                                 NULL, (xdrproc_t) xdr_void, NULL, to);
281           if (rpc_stat == RPC_PROGVERSMISMATCH)
282             {
283               clnt_geterr (client, &rpcerr);
284               minvers = rpcerr.re_vers.low;
285               maxvers = rpcerr.re_vers.high;
286             }
287           else if (rpc_stat == RPC_SUCCESS)
288             {
289               /*
290                * It also supports version MAX_VERS.
291                * Looks like we have a wise guy.
292                * OK, we give them information on all
293                * 4 billion versions they support...
294                */
295               minvers = 0;
296               maxvers = MAX_VERS;
297             }
298           else
299             {
300               (void) pstatus (client, prognum, MAX_VERS);
301               exit (1);
302             }
303         }
304       else
305         {
306           (void) pstatus (client, prognum, (u_long) 0);
307           exit (1);
308         }
309       clnt_destroy (client);
310       for (vers = minvers; vers <= maxvers; vers++)
311         {
312           addr.sin_port = htons (portnum);
313           to.tv_sec = 5;
314           to.tv_usec = 0;
315           if ((client = clntudp_create (&addr, prognum, vers,
316                                         to, &sock)) == NULL)
317             {
318               clnt_pcreateerror ("rpcinfo");
319               printf (_("program %lu version %lu is not available\n"),
320                       prognum, vers);
321               exit (1);
322             }
323           to.tv_sec = 10;
324           to.tv_usec = 0;
325           rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
326                                 NULL, (xdrproc_t) xdr_void, NULL, to);
327           if (pstatus (client, prognum, vers) < 0)
328             failure = 1;
329           clnt_destroy (client);
330         }
331     }
332   else
333     {
334       vers = getvers (argv[2]);
335       addr.sin_port = htons (portnum);
336       to.tv_sec = 5;
337       to.tv_usec = 0;
338       if ((client = clntudp_create (&addr, prognum, vers,
339                                     to, &sock)) == NULL)
340         {
341           clnt_pcreateerror ("rpcinfo");
342           printf (_("program %lu version %lu is not available\n"),
343                   prognum, vers);
344           exit (1);
345         }
346       to.tv_sec = 10;
347       to.tv_usec = 0;
348       rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
349                             (xdrproc_t) xdr_void, NULL, to);
350       if (pstatus (client, prognum, vers) < 0)
351         failure = 1;
352     }
353   (void) close (sock);          /* Close it up again */
354   if (failure)
355     exit (1);
356 }
357
358 static void
359 tcpping (portnum, argc, argv)
360      u_short portnum;
361      int argc;
362      char **argv;
363 {
364   struct timeval to;
365   struct sockaddr_in addr;
366   enum clnt_stat rpc_stat;
367   CLIENT *client;
368   u_long prognum, vers, minvers, maxvers;
369   int sock = RPC_ANYSOCK;
370   struct rpc_err rpcerr;
371   int failure;
372
373   if (argc < 2 || argc > 3)
374     {
375       usage (stderr);
376       exit (1);
377     }
378   prognum = getprognum (argv[1]);
379   get_inet_address (&addr, argv[0]);
380   failure = 0;
381   if (argc == 2)
382     {
383       /*
384        * A call to version 0 should fail with a program/version
385        * mismatch, and give us the range of versions supported.
386        */
387       addr.sin_port = htons (portnum);
388       if ((client = clnttcp_create (&addr, prognum, MIN_VERS,
389                                     &sock, 0, 0)) == NULL)
390         {
391           clnt_pcreateerror ("rpcinfo");
392           printf (_("program %lu is not available\n"), prognum);
393           exit (1);
394         }
395       to.tv_sec = 10;
396       to.tv_usec = 0;
397       rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void, NULL,
398                             (xdrproc_t) xdr_void, NULL, to);
399       if (rpc_stat == RPC_PROGVERSMISMATCH)
400         {
401           clnt_geterr (client, &rpcerr);
402           minvers = rpcerr.re_vers.low;
403           maxvers = rpcerr.re_vers.high;
404         }
405       else if (rpc_stat == RPC_SUCCESS)
406         {
407           /*
408            * Oh dear, it DOES support version 0.
409            * Let's try version MAX_VERS.
410            */
411           addr.sin_port = htons (portnum);
412           if ((client = clnttcp_create (&addr, prognum, MAX_VERS,
413                                         &sock, 0, 0)) == NULL)
414             {
415               clnt_pcreateerror ("rpcinfo");
416               printf (_("program %lu version %lu is not available\n"),
417                       prognum, MAX_VERS);
418               exit (1);
419             }
420           to.tv_sec = 10;
421           to.tv_usec = 0;
422           rpc_stat = clnt_call (client, NULLPROC, (xdrproc_t) xdr_void,
423                                 NULL, (xdrproc_t) xdr_void, NULL, to);
424           if (rpc_stat == RPC_PROGVERSMISMATCH)
425             {
426               clnt_geterr (client, &rpcerr);
427               minvers = rpcerr.re_vers.low;
428               maxvers = rpcerr.re_vers.high;
429             }
430           else if (rpc_stat == RPC_SUCCESS)
431             {
432               /*
433                * It also supports version MAX_VERS.
434                * Looks like we have a wise guy.
435                * OK, we give them information on all
436                * 4 billion versions they support...
437                */
438               minvers = 0;
439               maxvers = MAX_VERS;
440             }
441           else
442             {
443               (void) pstatus (client, prognum, MAX_VERS);
444               exit (1);
445             }
446         }
447       else
448         {
449           (void) pstatus (client, prognum, MIN_VERS);
450           exit (1);
451         }
452       clnt_destroy (client);
453       (void) close (sock);
454       sock = RPC_ANYSOCK;       /* Re-initialize it for later */
455       for (vers = minvers; vers <= maxvers; vers++)
456         {
457           addr.sin_port = htons (portnum);
458           if ((client = clnttcp_create (&addr, prognum, vers,
459                                         &sock, 0, 0)) == NULL)
460             {
461               clnt_pcreateerror ("rpcinfo");
462               printf (_("program %lu version %lu is not available\n"),
463                       prognum, vers);
464               exit (1);
465             }
466           to.tv_usec = 0;
467           to.tv_sec = 10;
468           rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
469                                 (xdrproc_t) xdr_void, NULL, to);
470           if (pstatus (client, prognum, vers) < 0)
471             failure = 1;
472           clnt_destroy (client);
473           (void) close (sock);
474           sock = RPC_ANYSOCK;
475         }
476     }
477   else
478     {
479       vers = getvers (argv[2]);
480       addr.sin_port = htons (portnum);
481       if ((client = clnttcp_create (&addr, prognum, vers, &sock,
482                                     0, 0)) == NULL)
483         {
484           clnt_pcreateerror ("rpcinfo");
485           printf (_("program %lu version %lu is not available\n"),
486                   prognum, vers);
487           exit (1);
488         }
489       to.tv_usec = 0;
490       to.tv_sec = 10;
491       rpc_stat = clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
492                             (xdrproc_t) xdr_void, NULL, to);
493       if (pstatus (client, prognum, vers) < 0)
494         failure = 1;
495     }
496   if (failure)
497     exit (1);
498 }
499
500 /*
501  * This routine should take a pointer to an "rpc_err" structure, rather than
502  * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
503  * a CLIENT structure rather than a pointer to an "rpc_err" structure.
504  * As such, we have to keep the CLIENT structure around in order to print
505  * a good error message.
506  */
507 static int
508 pstatus (client, prognum, vers)
509      register CLIENT *client;
510      u_long prognum;
511      u_long vers;
512 {
513   struct rpc_err rpcerr;
514
515   clnt_geterr (client, &rpcerr);
516   if (rpcerr.re_status != RPC_SUCCESS)
517     {
518       clnt_perror (client, "rpcinfo");
519       printf (_("program %lu version %lu is not available\n"), prognum, vers);
520       return -1;
521     }
522   else
523     {
524       printf (_("program %lu version %lu ready and waiting\n"), prognum, vers);
525       return 0;
526     }
527 }
528
529 static void
530 pmapdump (argc, argv)
531      int argc;
532      char **argv;
533 {
534   struct sockaddr_in server_addr;
535   register struct hostent *hp;
536   struct pmaplist *head = NULL;
537   int socket = RPC_ANYSOCK;
538   struct timeval minutetimeout;
539   register CLIENT *client;
540   struct rpcent *rpc;
541
542   if (argc > 1)
543     {
544       usage (stderr);
545       exit (1);
546     }
547   if (argc == 1)
548     get_inet_address (&server_addr, argv[0]);
549   else
550     {
551       bzero ((char *) &server_addr, sizeof server_addr);
552       server_addr.sin_family = AF_INET;
553       if ((hp = gethostbyname ("localhost")) != NULL)
554         memcpy ((caddr_t) & server_addr.sin_addr, hp->h_addr,
555                  hp->h_length);
556       else
557         server_addr.sin_addr.s_addr = inet_addr ("0.0.0.0");
558     }
559   minutetimeout.tv_sec = 60;
560   minutetimeout.tv_usec = 0;
561   server_addr.sin_port = htons (PMAPPORT);
562   if ((client = clnttcp_create (&server_addr, PMAPPROG,
563                                 PMAPVERS, &socket, 50, 500)) == NULL)
564     {
565       clnt_pcreateerror (_("rpcinfo: can't contact portmapper"));
566       exit (1);
567     }
568   if (clnt_call (client, PMAPPROC_DUMP, (xdrproc_t) xdr_void, NULL,
569                  (xdrproc_t) xdr_pmaplist, (caddr_t) &head,
570                  minutetimeout) != RPC_SUCCESS)
571     {
572       fputs (_("rpcinfo: can't contact portmapper"), stderr);
573       fputs (": ", stderr);
574       clnt_perror (client, "rpcinfo");
575       exit (1);
576     }
577   if (head == NULL)
578     {
579       fputs (_("No remote programs registered.\n"), stdout);
580     }
581   else
582     {
583       fputs (_("   program vers proto   port\n"), stdout);
584       for (; head != NULL; head = head->pml_next)
585         {
586           printf ("%10ld%5ld",
587                   head->pml_map.pm_prog,
588                   head->pml_map.pm_vers);
589           if (head->pml_map.pm_prot == IPPROTO_UDP)
590             printf ("%6s", "udp");
591           else if (head->pml_map.pm_prot == IPPROTO_TCP)
592             printf ("%6s", "tcp");
593           else
594             printf ("%6ld", head->pml_map.pm_prot);
595           printf ("%7ld", head->pml_map.pm_port);
596           rpc = getrpcbynumber (head->pml_map.pm_prog);
597           if (rpc)
598             printf ("  %s\n", rpc->r_name);
599           else
600             printf ("\n");
601         }
602     }
603 }
604
605 /*
606  * reply_proc collects replies from the broadcast.
607  * to get a unique list of responses the output of rpcinfo should
608  * be piped through sort(1) and then uniq(1).
609  */
610
611 /*ARGSUSED */
612 static bool_t
613 reply_proc (res, who)
614      void *res;                 /* Nothing comes back */
615      struct sockaddr_in *who;   /* Who sent us the reply */
616 {
617   register struct hostent *hp;
618
619   hp = gethostbyaddr ((char *) &who->sin_addr, sizeof who->sin_addr,
620                       AF_INET);
621   printf ("%s %s\n", inet_ntoa (who->sin_addr),
622           (hp == NULL) ? _("(unknown)") : hp->h_name);
623   return FALSE;
624 }
625
626 static void
627 brdcst (argc, argv)
628      int argc;
629      char **argv;
630 {
631   enum clnt_stat rpc_stat;
632   u_long prognum, vers;
633
634   if (argc != 2)
635     {
636       usage (stderr);
637       exit (1);
638     }
639   prognum = getprognum (argv[0]);
640   vers = getvers (argv[1]);
641   rpc_stat = clnt_broadcast (prognum, vers, NULLPROC, (xdrproc_t) xdr_void,
642                              NULL, (xdrproc_t) xdr_void, NULL,
643                              (resultproc_t) reply_proc);
644   if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT))
645     {
646       fprintf (stderr, _("rpcinfo: broadcast failed: %s\n"),
647                clnt_sperrno (rpc_stat));
648       exit (1);
649     }
650   exit (0);
651 }
652
653 static void
654 deletereg (argc, argv)
655      int argc;
656      char **argv;
657 {
658   u_long prog_num, version_num;
659
660   if (argc != 2)
661     {
662       usage (stderr);
663       exit (1);
664     }
665   if (getuid ())
666     {                           /* This command allowed only to root */
667       fputs (_("Sorry. You are not root\n"), stderr);
668       exit (1);
669     }
670   prog_num = getprognum (argv[0]);
671   version_num = getvers (argv[1]);
672   if ((pmap_unset (prog_num, version_num)) == 0)
673     {
674       fprintf (stderr, _("rpcinfo: Could not delete registration for prog %s version %s\n"),
675                argv[0], argv[1]);
676       exit (1);
677     }
678 }
679
680 static void
681 usage (FILE *stream)
682 {
683   fputs (_("Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n"),
684          stream);
685   fputs (_("       rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n"),
686          stream);
687   fputs (_("       rpcinfo -p [ host ]\n"), stream);
688   fputs (_("       rpcinfo -b prognum versnum\n"), stream);
689   fputs (_("       rpcinfo -d prognum versnum\n"), stream);
690   fputc ('\n', stream);
691   fprintf (stream, _("\
692 For bug reporting instructions, please see:\n\
693 %s.\n"), REPORT_BUGS_TO);
694 }
695
696 static void
697 print_version (void)
698 {
699   printf ("rpcinfo %s%s\n", PKGVERSION, VERSION);
700 }
701
702 static u_long
703 getprognum (arg)
704      char *arg;
705 {
706   register struct rpcent *rpc;
707   register u_long prognum;
708
709   if (isalpha (*arg))
710     {
711       rpc = getrpcbyname (arg);
712       if (rpc == NULL)
713         {
714           fprintf (stderr, _("rpcinfo: %s is unknown service\n"), arg);
715           exit (1);
716         }
717       prognum = rpc->r_number;
718     }
719   else
720     {
721       prognum = (u_long) atoi (arg);
722     }
723
724   return prognum;
725 }
726
727 static u_long
728 getvers (arg)
729      char *arg;
730 {
731   register u_long vers;
732
733   vers = (int) atoi (arg);
734   return vers;
735 }
736
737 static void
738 get_inet_address (addr, host)
739      struct sockaddr_in *addr;
740      char *host;
741 {
742   register struct hostent *hp;
743
744   bzero ((char *) addr, sizeof *addr);
745   addr->sin_addr.s_addr = (u_long) inet_addr (host);
746   if (addr->sin_addr.s_addr == INADDR_NONE
747       || addr->sin_addr.s_addr == INADDR_ANY)
748     {
749       if ((hp = gethostbyname (host)) == NULL)
750         {
751           fprintf (stderr, _("rpcinfo: %s is unknown host\n"),
752                    host);
753           exit (1);
754         }
755       memmove ((char *) &addr->sin_addr, hp->h_addr, hp->h_length);
756     }
757   addr->sin_family = AF_INET;
758 }