1 #ifndef lint 2 static char sccsid[] = "@(#)query.c 4.6 12/21/83"; 3 #endif 4 5 #include <sys/param.h> 6 #include <sys/protosw.h> 7 #include <sys/socket.h> 8 #include <sys/time.h> 9 #include <netinet/in.h> 10 #include <errno.h> 11 #include <stdio.h> 12 #include <netdb.h> 13 #include "../protocol.h" 14 15 #define WTIME 5 /* Time to wait for responses */ 16 17 int s; 18 char packet[MAXPACKETSIZE]; 19 20 main(argc, argv) 21 int argc; 22 char *argv[]; 23 { 24 int cc, count, bits; 25 struct sockaddr from; 26 int fromlen = sizeof(from); 27 struct timeval notime; 28 29 if (argc < 2) { 30 printf("usage: query hosts...\n"); 31 exit(1); 32 } 33 s = socket(AF_INET, SOCK_DGRAM, 0); 34 if (s < 0) { 35 perror("socket"); 36 exit(2); 37 } 38 39 argv++, argc--; 40 count = argc; 41 while (argc > 0) { 42 query(*argv); 43 argv++, argc--; 44 } 45 46 /* 47 * Listen for returning packets; 48 * may be more than one packet per host. 49 */ 50 bits = 1 << s; 51 bzero(¬ime, sizeof(notime)); 52 while (count > 0 || select(20, &bits, 0, 0, ¬ime) > 0) { 53 cc = recvfrom(s, packet, sizeof (packet), 0, 54 &from, &fromlen); 55 if (cc <= 0) { 56 if (cc < 0) { 57 perror("recvfrom"); 58 (void) close(s); 59 exit(1); 60 } 61 continue; 62 } 63 rip_input(&from, cc); 64 count--; 65 } 66 } 67 68 query(host) 69 char *host; 70 { 71 struct sockaddr_in router; 72 register struct rip *msg = (struct rip *)packet; 73 struct hostent *hp; 74 struct servent *sp; 75 76 bzero((char *)&router, sizeof (router)); 77 hp = gethostbyname(host); 78 if (hp == 0) { 79 printf("%s: unknown\n", host); 80 exit(1); 81 } 82 bcopy(hp->h_addr, &router.sin_addr, hp->h_length); 83 router.sin_family = AF_INET; 84 sp = getservbyname("router", "udp"); 85 if (sp == 0) { 86 printf("udp/router: service unknown\n"); 87 exit(1); 88 } 89 router.sin_port = sp->s_port; 90 msg->rip_cmd = RIPCMD_REQUEST; 91 msg->rip_vers = RIPVERSION; 92 msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); 93 msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); 94 if (sendto(s, packet, sizeof (struct rip), 0, 95 &router, sizeof(router)) < 0) 96 perror(host); 97 } 98 99 /* 100 * Handle an incoming routing packet. 101 */ 102 rip_input(from, size) 103 struct sockaddr_in *from; 104 int size; 105 { 106 register struct rip *msg = (struct rip *)packet; 107 struct netinfo *n; 108 char *name; 109 struct hostent *hp; 110 struct netent *np; 111 112 if (msg->rip_cmd != RIPCMD_RESPONSE) 113 return; 114 hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), AF_INET); 115 name = hp == 0 ? "???" : hp->h_name; 116 printf("from %s(%s):\n", name, inet_ntoa(from->sin_addr)); 117 size -= sizeof (int); 118 n = msg->rip_nets; 119 while (size > 0) { 120 register struct sockaddr_in *sin; 121 122 if (size < sizeof (struct netinfo)) 123 break; 124 if (msg->rip_vers > 0) { 125 n->rip_dst.sa_family = 126 ntohs(n->rip_dst.sa_family); 127 n->rip_metric = ntohl(n->rip_metric); 128 } 129 sin = (struct sockaddr_in *)&n->rip_dst; 130 if (inet_lnaof(sin->sin_addr) == INADDR_ANY) { 131 np = getnetbyaddr(inet_netof(sin->sin_addr), AF_INET); 132 name = np ? np->n_name : "???"; 133 } else { 134 hp = gethostbyaddr(&sin->sin_addr, 135 sizeof (struct in_addr), AF_INET); 136 name = hp ? hp->h_name : "???"; 137 } 138 printf("\t%s(%s), metric %d\n", name, 139 inet_ntoa(sin->sin_addr), n->rip_metric); 140 size -= sizeof (struct netinfo), n++; 141 } 142 } 143 144 timeout() 145 { 146 timedout = 1; 147 } 148