16918Ssam #ifndef lint 2*8339Ssam static char sccsid[] = "@(#)query.c 4.3 10/06/82"; 36918Ssam #endif 46918Ssam 56918Ssam #include <sys/param.h> 66918Ssam #include <sys/protosw.h> 76918Ssam #include <sys/socket.h> 86918Ssam #include <net/in.h> 96918Ssam #include <errno.h> 106918Ssam #include <stdio.h> 11*8339Ssam #include <netdb.h> 126918Ssam #include "rip.h" 136918Ssam 146918Ssam int s; 156918Ssam char packet[MAXPACKETSIZE]; 166918Ssam 176918Ssam main(argc, argv) 186918Ssam int argc; 196918Ssam char *argv[]; 206918Ssam { 216918Ssam int cc, count; 226918Ssam struct sockaddr from; 236918Ssam 246918Ssam if (argc < 2) { 256918Ssam printf("usage: query hosts...\n"); 266918Ssam exit(1); 276918Ssam } 28*8339Ssam s = socket(SOCK_DGRAM, 0, 0, 0); 296918Ssam if (s < 0) { 306918Ssam perror("socket"); 316918Ssam exit(2); 326918Ssam } 336918Ssam argv++, argc--; 346918Ssam count = argc; 356918Ssam while (argc > 0) { 366918Ssam query(*argv); 376918Ssam argv++, argc--; 386918Ssam } 396918Ssam 406918Ssam /* 416918Ssam * Listen for returning packets 426918Ssam */ 436918Ssam while (count > 0) { 446918Ssam cc = receive(s, &from, packet, sizeof (packet)); 456918Ssam if (cc <= 0) { 466918Ssam if (cc < 0) { 476918Ssam perror("receive"); 486918Ssam (void) close(s); 496918Ssam exit(1); 506918Ssam } 516918Ssam continue; 526918Ssam } 536918Ssam rip_input(&from, cc); 546918Ssam count--; 556918Ssam } 566918Ssam } 576918Ssam 586918Ssam query(host) 596918Ssam char *host; 606918Ssam { 616918Ssam struct sockaddr_in router; 626918Ssam register struct rip *msg = (struct rip *)packet; 63*8339Ssam struct hostent *hp; 64*8339Ssam struct servent *sp; 656918Ssam 666918Ssam bzero((char *)&router, sizeof (router)); 67*8339Ssam hp = gethostbyname(host); 68*8339Ssam if (hp == 0) { 696918Ssam printf("%s: unknown\n", host); 706918Ssam exit(1); 716918Ssam } 72*8339Ssam bcopy(hp->h_addr, &router.sin_addr, hp->h_length); 736918Ssam router.sin_family = AF_INET; 74*8339Ssam sp = getservbyname("router", "udp"); 75*8339Ssam if (sp == 0) { 76*8339Ssam printf("udp/router: service unknown\n"); 77*8339Ssam exit(1); 78*8339Ssam } 79*8339Ssam router.sin_port = htons(sp->s_port); 806918Ssam msg->rip_cmd = RIPCMD_REQUEST; 816918Ssam msg->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; 826918Ssam msg->rip_nets[0].rip_metric = HOPCNT_INFINITY; 836918Ssam if (send(s, &router, packet, sizeof (struct rip)) < 0) 846918Ssam perror(host); 856918Ssam } 866918Ssam 876918Ssam /* 886918Ssam * Handle an incoming routing packet. 896918Ssam */ 906918Ssam rip_input(from, size) 916918Ssam struct sockaddr_in *from; 926918Ssam int size; 936918Ssam { 946918Ssam register struct rip *msg = (struct rip *)packet; 956918Ssam struct netinfo *n; 966918Ssam char *name; 97*8339Ssam struct hostent *hp; 98*8339Ssam struct netent *np; 996918Ssam 1006918Ssam if (msg->rip_cmd != RIPCMD_RESPONSE) 1016918Ssam return; 102*8339Ssam hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr)); 103*8339Ssam name = hp == 0 ? "???" : hp->h_name; 1046918Ssam printf("from %s(%x):\n", name, from->sin_addr); 1056918Ssam size -= sizeof (int); 1066918Ssam n = msg->rip_nets; 1076918Ssam while (size > 0) { 1086918Ssam register struct sockaddr_in *sin; 1096918Ssam 1106918Ssam if (size < sizeof (struct netinfo)) 1116918Ssam break; 1126918Ssam sin = (struct sockaddr_in *)&n->rip_dst; 113*8339Ssam if (in_lnaof(sin->sin_addr) == INADDR_ANY) { 114*8339Ssam np = getnetbyaddr(in_netof(sin->sin_addr)); 115*8339Ssam name = np ? np->n_name : "???"; 116*8339Ssam } else { 117*8339Ssam hp = gethostbyaddr(&sin->sin_addr, 118*8339Ssam sizeof (struct in_addr)); 119*8339Ssam name = hp ? hp->h_name : "???"; 120*8339Ssam } 1216918Ssam printf("\t%s(%x), metric %d\n", name, 1226918Ssam sin->sin_addr, n->rip_metric); 1236918Ssam size -= sizeof (struct netinfo), n++; 1246918Ssam } 1256918Ssam } 126*8339Ssam 127*8339Ssam /* 128*8339Ssam * Return the network number from an internet 129*8339Ssam * address; handles class a/b/c network #'s. 130*8339Ssam */ 131*8339Ssam in_netof(in) 132*8339Ssam struct in_addr in; 133*8339Ssam { 134*8339Ssam #if vax || pdp11 135*8339Ssam register u_long net; 136*8339Ssam 137*8339Ssam if ((in.s_addr&IN_CLASSA) == 0) 138*8339Ssam return (in.s_addr & IN_CLASSA_NET); 139*8339Ssam if ((in.s_addr&IN_CLASSB) == 0) 140*8339Ssam return ((int)htons((u_short)(in.s_addr & IN_CLASSB_NET))); 141*8339Ssam net = htonl((u_long)(in.s_addr & IN_CLASSC_NET)); 142*8339Ssam net >>= 8; 143*8339Ssam return ((int)net); 144*8339Ssam #else 145*8339Ssam return (IN_NETOF(in)); 146*8339Ssam #endif 147*8339Ssam } 148*8339Ssam 149*8339Ssam /* 150*8339Ssam * Return the local network address portion of an 151*8339Ssam * internet address; handles class a/b/c network 152*8339Ssam * number formats. 153*8339Ssam */ 154*8339Ssam in_lnaof(in) 155*8339Ssam struct in_addr in; 156*8339Ssam { 157*8339Ssam #if vax || pdp11 158*8339Ssam #define IN_LNAOF(in) \ 159*8339Ssam (((in).s_addr&IN_CLASSA) == 0 ? (in).s_addr&IN_CLASSA_LNA : \ 160*8339Ssam ((in).s_addr&IN_CLASSB) == 0 ? (in).s_addr&IN_CLASSB_LNA : \ 161*8339Ssam (in).s_addr&IN_CLASSC_LNA) 162*8339Ssam return ((int)htonl((u_long)IN_LNAOF(in))); 163*8339Ssam #else 164*8339Ssam return (IN_LNAOF(in)); 165*8339Ssam #endif 166*8339Ssam } 167