122643Sdist /* 222643Sdist * Copyright (c) 1980 Regents of the University of California. 322643Sdist * All rights reserved. The Berkeley software License Agreement 422643Sdist * specifies the terms and conditions for redistribution. 522643Sdist */ 622643Sdist 76918Ssam #ifndef lint 8*28205Skarels static char sccsid[] = "@(#)query.c 5.7 (Berkeley) 05/15/86"; 922643Sdist #endif not lint 106918Ssam 116918Ssam #include <sys/param.h> 126918Ssam #include <sys/protosw.h> 136918Ssam #include <sys/socket.h> 1415760Skarels #include <sys/time.h> 1515760Skarels #include <netinet/in.h> 166918Ssam #include <errno.h> 176918Ssam #include <stdio.h> 188339Ssam #include <netdb.h> 1925382Skarels #include <protocols/routed.h> 206918Ssam 2127344Skarels #define WTIME 5 /* Time to wait for all responses */ 2227344Skarels #define STIME 500000 /* usec to wait for another response */ 2315760Skarels 246918Ssam int s; 2522547Skarels int timedout, timeout(); 266918Ssam char packet[MAXPACKETSIZE]; 2722547Skarels extern int errno; 2826146Skarels int nflag; 296918Ssam 306918Ssam main(argc, argv) 316918Ssam int argc; 326918Ssam char *argv[]; 336918Ssam { 34*28205Skarels int cc, count, bits; 356918Ssam struct sockaddr from; 3615760Skarels int fromlen = sizeof(from); 3727344Skarels struct timeval shorttime; 386918Ssam 396918Ssam if (argc < 2) { 4026146Skarels usage: 4126146Skarels printf("usage: query [ -n ] hosts...\n"); 426918Ssam exit(1); 436918Ssam } 4415760Skarels s = socket(AF_INET, SOCK_DGRAM, 0); 456918Ssam if (s < 0) { 466918Ssam perror("socket"); 476918Ssam exit(2); 486918Ssam } 4915760Skarels 506918Ssam argv++, argc--; 5126146Skarels if (*argv[0] == '-') { 5226159Skarels switch (argv[0][1]) { 5326146Skarels case 'n': 5426146Skarels nflag++; 5526146Skarels break; 5626146Skarels default: 5726146Skarels goto usage; 5826146Skarels } 5926146Skarels argc--, argv++; 6026146Skarels } 616918Ssam while (argc > 0) { 626918Ssam query(*argv); 63*28205Skarels count++; 646918Ssam argv++, argc--; 656918Ssam } 666918Ssam 676918Ssam /* 6815760Skarels * Listen for returning packets; 6915760Skarels * may be more than one packet per host. 706918Ssam */ 7115760Skarels bits = 1 << s; 7227344Skarels bzero(&shorttime, sizeof(shorttime)); 7327344Skarels shorttime.tv_usec = STIME; 7422547Skarels signal(SIGALRM, timeout); 7522547Skarels alarm(WTIME); 7622547Skarels while ((count > 0 && !timedout) || 7727344Skarels select(20, &bits, 0, 0, &shorttime) > 0) { 7815760Skarels cc = recvfrom(s, packet, sizeof (packet), 0, 7915760Skarels &from, &fromlen); 806918Ssam if (cc <= 0) { 816918Ssam if (cc < 0) { 8222547Skarels if (errno == EINTR) 8322547Skarels continue; 8415760Skarels perror("recvfrom"); 856918Ssam (void) close(s); 866918Ssam exit(1); 876918Ssam } 886918Ssam continue; 896918Ssam } 906918Ssam rip_input(&from, cc); 916918Ssam count--; 926918Ssam } 936918Ssam } 946918Ssam 956918Ssam query(host) 966918Ssam char *host; 976918Ssam { 986918Ssam struct sockaddr_in router; 996918Ssam register struct rip *msg = (struct rip *)packet; 1008339Ssam struct hostent *hp; 1018339Ssam struct servent *sp; 1026918Ssam 1036918Ssam bzero((char *)&router, sizeof (router)); 10426146Skarels router.sin_family = AF_INET; 10526146Skarels router.sin_addr.s_addr = inet_addr(host); 10626146Skarels if (router.sin_addr.s_addr == -1) { 10726146Skarels hp = gethostbyname(host); 10826146Skarels if (hp == 0) { 10926146Skarels printf("%s: unknown\n", host); 11026146Skarels exit(1); 11126146Skarels } 11226146Skarels bcopy(hp->h_addr, &router.sin_addr, hp->h_length); 1136918Ssam } 1148339Ssam sp = getservbyname("router", "udp"); 1158339Ssam if (sp == 0) { 1168339Ssam printf("udp/router: service unknown\n"); 1178339Ssam exit(1); 1188339Ssam } 11915760Skarels router.sin_port = sp->s_port; 1206918Ssam msg->rip_cmd = RIPCMD_REQUEST; 12115760Skarels msg->rip_vers = RIPVERSION; 12215760Skarels msg->rip_nets[0].rip_dst.sa_family = htons(AF_UNSPEC); 12315760Skarels msg->rip_nets[0].rip_metric = htonl(HOPCNT_INFINITY); 12415760Skarels if (sendto(s, packet, sizeof (struct rip), 0, 12515760Skarels &router, sizeof(router)) < 0) 1266918Ssam perror(host); 1276918Ssam } 1286918Ssam 1296918Ssam /* 1306918Ssam * Handle an incoming routing packet. 1316918Ssam */ 1326918Ssam rip_input(from, size) 1336918Ssam struct sockaddr_in *from; 1346918Ssam int size; 1356918Ssam { 1366918Ssam register struct rip *msg = (struct rip *)packet; 137*28205Skarels register struct netinfo *n; 1386918Ssam char *name; 13922547Skarels int lna, net, subnet; 1408339Ssam struct hostent *hp; 1418339Ssam struct netent *np; 1426918Ssam 1436918Ssam if (msg->rip_cmd != RIPCMD_RESPONSE) 1446918Ssam return; 14526959Skarels printf("%d bytes from ", size); 14626146Skarels if (nflag) 14726146Skarels printf("%s:\n", inet_ntoa(from->sin_addr)); 14826146Skarels else { 14926146Skarels hp = gethostbyaddr(&from->sin_addr, sizeof (struct in_addr), 15026146Skarels AF_INET); 15126146Skarels name = hp == 0 ? "???" : hp->h_name; 15226146Skarels printf("%s(%s):\n", name, inet_ntoa(from->sin_addr)); 15326146Skarels } 1546918Ssam size -= sizeof (int); 1556918Ssam n = msg->rip_nets; 1566918Ssam while (size > 0) { 157*28205Skarels if (size < sizeof (struct netinfo)) 158*28205Skarels break; 159*28205Skarels if (msg->rip_vers > 0) { 160*28205Skarels n->rip_dst.sa_family = 161*28205Skarels ntohs(n->rip_dst.sa_family); 162*28205Skarels n->rip_metric = ntohl(n->rip_metric); 163*28205Skarels } 164*28205Skarels switch (n->rip_dst.sa_family) { 1656918Ssam 166*28205Skarels case AF_INET: 167*28205Skarels { register struct sockaddr_in *sin; 168*28205Skarels 1696918Ssam sin = (struct sockaddr_in *)&n->rip_dst; 17022547Skarels net = inet_netof(sin->sin_addr); 17122547Skarels subnet = inet_subnetof(sin->sin_addr); 17222547Skarels lna = inet_lnaof(sin->sin_addr); 17322547Skarels name = "???"; 17426146Skarels if (!nflag) { 175*28205Skarels if (sin->sin_addr.s_addr == 0) 176*28205Skarels name = "default"; 177*28205Skarels else if (lna == INADDR_ANY) { 17826146Skarels np = getnetbyaddr(net, AF_INET); 17926146Skarels if (np) 18026146Skarels name = np->n_name; 18126146Skarels else if (net == 0) 18226146Skarels name = "default"; 18326959Skarels } else if ((lna & 0xff) == 0 && 18426146Skarels (np = getnetbyaddr(subnet, AF_INET))) { 18526146Skarels struct in_addr subnaddr, inet_makeaddr(); 18622547Skarels 18726146Skarels subnaddr = inet_makeaddr(subnet, INADDR_ANY); 18826146Skarels if (bcmp(&sin->sin_addr, &subnaddr, 18926146Skarels sizeof(subnaddr)) == 0) 19026146Skarels name = np->n_name; 19126146Skarels else 19226146Skarels goto host; 19326146Skarels } else { 19426146Skarels host: 19526146Skarels hp = gethostbyaddr(&sin->sin_addr, 19626146Skarels sizeof (struct in_addr), AF_INET); 19726146Skarels if (hp) 19826146Skarels name = hp->h_name; 19926146Skarels } 20026146Skarels printf("\t%s(%s), metric %d\n", name, 20126146Skarels inet_ntoa(sin->sin_addr), n->rip_metric); 20226146Skarels } else 20326146Skarels printf("\t%s, metric %d\n", 20426146Skarels inet_ntoa(sin->sin_addr), n->rip_metric); 205*28205Skarels break; 206*28205Skarels } 207*28205Skarels 208*28205Skarels default: 209*28205Skarels { u_short *p = (u_short *)n->rip_dst.sa_data; 210*28205Skarels 211*28205Skarels printf("\t(af %d) %x %x %x %x %x %x %x, metric %d\n", 212*28205Skarels p[0], p[1], p[2], p[3], p[4], p[5], p[6], 213*28205Skarels n->rip_dst.sa_family, 214*28205Skarels n->rip_metric); 215*28205Skarels break; 216*28205Skarels } 217*28205Skarels 218*28205Skarels } 219*28205Skarels size -= sizeof (struct netinfo), n++; 2206918Ssam } 2216918Ssam } 22215760Skarels 22315760Skarels timeout() 22415760Skarels { 22515760Skarels timedout = 1; 22615760Skarels } 22722547Skarels 22822547Skarels /* 22922547Skarels * Return the possible subnetwork number from an internet address. 23022547Skarels * SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING 23122547Skarels * INSIDE OF THE HOST PART. We can only believe this if we have other 23222547Skarels * information (e.g., we can find a name for this number). 23322547Skarels */ 23422547Skarels inet_subnetof(in) 23522547Skarels struct in_addr in; 23622547Skarels { 23722547Skarels register u_long i = ntohl(in.s_addr); 23822547Skarels 23925382Skarels if (IN_CLASSA(i)) 24025382Skarels return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); 24125382Skarels else if (IN_CLASSB(i)) 24222547Skarels return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); 24325382Skarels else 24425382Skarels return ((i & 0xffffffc0) >> 28); 24522547Skarels } 246