16918Ssam #ifndef lint 2*15760Skarels static char sccsid[] = "@(#)query.c 4.6 12/21/83"; 36918Ssam #endif 46918Ssam 56918Ssam #include <sys/param.h> 66918Ssam #include <sys/protosw.h> 76918Ssam #include <sys/socket.h> 8*15760Skarels #include <sys/time.h> 9*15760Skarels #include <netinet/in.h> 106918Ssam #include <errno.h> 116918Ssam #include <stdio.h> 128339Ssam #include <netdb.h> 13*15760Skarels #include "../protocol.h" 146918Ssam 15*15760Skarels #define WTIME 5 /* Time to wait for responses */ 16*15760Skarels 176918Ssam int s; 186918Ssam char packet[MAXPACKETSIZE]; 196918Ssam 206918Ssam main(argc, argv) 216918Ssam int argc; 226918Ssam char *argv[]; 236918Ssam { 24*15760Skarels int cc, count, bits; 256918Ssam struct sockaddr from; 26*15760Skarels int fromlen = sizeof(from); 27*15760Skarels struct timeval notime; 286918Ssam 296918Ssam if (argc < 2) { 306918Ssam printf("usage: query hosts...\n"); 316918Ssam exit(1); 326918Ssam } 33*15760Skarels s = socket(AF_INET, SOCK_DGRAM, 0); 346918Ssam if (s < 0) { 356918Ssam perror("socket"); 366918Ssam exit(2); 376918Ssam } 38*15760Skarels 396918Ssam argv++, argc--; 406918Ssam count = argc; 416918Ssam while (argc > 0) { 426918Ssam query(*argv); 436918Ssam argv++, argc--; 446918Ssam } 456918Ssam 466918Ssam /* 47*15760Skarels * Listen for returning packets; 48*15760Skarels * may be more than one packet per host. 496918Ssam */ 50*15760Skarels bits = 1 << s; 51*15760Skarels bzero(¬ime, sizeof(notime)); 52*15760Skarels while (count > 0 || select(20, &bits, 0, 0, ¬ime) > 0) { 53*15760Skarels cc = recvfrom(s, packet, sizeof (packet), 0, 54*15760Skarels &from, &fromlen); 556918Ssam if (cc <= 0) { 566918Ssam if (cc < 0) { 57*15760Skarels perror("recvfrom"); 586918Ssam (void) close(s); 596918Ssam exit(1); 606918Ssam } 616918Ssam continue; 626918Ssam } 636918Ssam rip_input(&from, cc); 646918Ssam count--; 656918Ssam } 666918Ssam } 676918Ssam 686918Ssam query(host) 696918Ssam char *host; 706918Ssam { 716918Ssam struct sockaddr_in router; 726918Ssam register struct rip *msg = (struct rip *)packet; 738339Ssam struct hostent *hp; 748339Ssam struct servent *sp; 756918Ssam 766918Ssam bzero((char *)&router, sizeof (router)); 778339Ssam hp = gethostbyname(host); 788339Ssam if (hp == 0) { 796918Ssam printf("%s: unknown\n", host); 806918Ssam exit(1); 816918Ssam } 828339Ssam bcopy(hp->h_addr, &router.sin_addr, hp->h_length); 836918Ssam router.sin_family = AF_INET; 848339Ssam sp = getservbyname("router", "udp"); 858339Ssam if (sp == 0) { 868339Ssam printf("udp/router: service unknown\n"); 878339Ssam exit(1); 888339Ssam } 89*15760Skarels router.sin_port = sp->s_port; 906918Ssam msg->rip_cmd = RIPCMD_REQUEST; 91*15760Skarels msg->rip_vers = RIPVERSION; 92*15760Skarels msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); 93*15760Skarels msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); 94*15760Skarels if (sendto(s, packet, sizeof (struct rip), 0, 95*15760Skarels &router, sizeof(router)) < 0) 966918Ssam perror(host); 976918Ssam } 986918Ssam 996918Ssam /* 1006918Ssam * Handle an incoming routing packet. 1016918Ssam */ 1026918Ssam rip_input(from, size) 1036918Ssam struct sockaddr_in *from; 1046918Ssam int size; 1056918Ssam { 1066918Ssam register struct rip *msg = (struct rip *)packet; 1076918Ssam struct netinfo *n; 1086918Ssam char *name; 1098339Ssam struct hostent *hp; 1108339Ssam struct netent *np; 1116918Ssam 1126918Ssam if (msg->rip_cmd != RIPCMD_RESPONSE) 1136918Ssam return; 1148344Ssam hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), AF_INET); 1158339Ssam name = hp == 0 ? "???" : hp->h_name; 116*15760Skarels printf("from %s(%s):\n", name, inet_ntoa(from->sin_addr)); 1176918Ssam size -= sizeof (int); 1186918Ssam n = msg->rip_nets; 1196918Ssam while (size > 0) { 1206918Ssam register struct sockaddr_in *sin; 1216918Ssam 1226918Ssam if (size < sizeof (struct netinfo)) 1236918Ssam break; 124*15760Skarels if (msg->rip_vers > 0) { 125*15760Skarels n->rip_dst.sa_family = 126*15760Skarels ntohs(n->rip_dst.sa_family); 127*15760Skarels n->rip_metric = ntohl(n->rip_metric); 128*15760Skarels } 1296918Ssam sin = (struct sockaddr_in *)&n->rip_dst; 1308365Ssam if (inet_lnaof(sin->sin_addr) == INADDR_ANY) { 1318365Ssam np = getnetbyaddr(inet_netof(sin->sin_addr), AF_INET); 1328339Ssam name = np ? np->n_name : "???"; 1338339Ssam } else { 1348339Ssam hp = gethostbyaddr(&sin->sin_addr, 1358344Ssam sizeof (struct in_addr), AF_INET); 1368339Ssam name = hp ? hp->h_name : "???"; 1378339Ssam } 138*15760Skarels printf("\t%s(%s), metric %d\n", name, 139*15760Skarels inet_ntoa(sin->sin_addr), n->rip_metric); 1406918Ssam size -= sizeof (struct netinfo), n++; 1416918Ssam } 1426918Ssam } 143*15760Skarels 144*15760Skarels timeout() 145*15760Skarels { 146*15760Skarels timedout = 1; 147*15760Skarels } 148