124265Ssklower /* 224326Ssklower * Copyright (c) 1983 Regents of the University of California. 324265Ssklower * All rights reserved. The Berkeley software License Agreement 424265Ssklower * specifies the terms and conditions for redistribution. 524265Ssklower */ 624265Ssklower 724265Ssklower #ifndef lint 824326Ssklower char copyright[] = 924326Ssklower "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1024326Ssklower All rights reserved.\n"; 1124265Ssklower #endif not lint 1224265Ssklower 1324326Ssklower #ifndef lint 14*26176Ssklower static char sccsid[] = "@(#)query.c 5.3 (Berkeley) 02/14/86"; 1524326Ssklower #endif not lint 1624326Ssklower 1724265Ssklower #include <sys/param.h> 1824265Ssklower #include <sys/protosw.h> 1924265Ssklower #include <sys/socket.h> 2024265Ssklower #include <sys/time.h> 2124265Ssklower #include <netinet/in.h> 2224265Ssklower #include <netns/ns.h> 2324265Ssklower #include <netns/idp.h> 2424265Ssklower #include <errno.h> 2524265Ssklower #include <stdio.h> 2624265Ssklower #include <netdb.h> 2724265Ssklower #include "../protocol.h" 2824265Ssklower #define IDPPORT_RIF 1 2924265Ssklower 3024265Ssklower #define WTIME 5 /* Time to wait for responses */ 3124265Ssklower 3224265Ssklower int s; 3324265Ssklower int timedout, timeout(); 3424265Ssklower char packet[MAXPACKETSIZE]; 3524265Ssklower extern int errno; 3624265Ssklower struct sockaddr_ns myaddr = {AF_NS}; 37*26176Ssklower char ns_ntoa(); 38*26176Ssklower struct ns_addr ns_addr(); 3924265Ssklower main(argc, argv) 4024265Ssklower int argc; 4124265Ssklower char *argv[]; 4224265Ssklower { 4324265Ssklower int cc, count, bits; 4424265Ssklower struct sockaddr from; 4524265Ssklower int fromlen = sizeof(from); 4624265Ssklower struct timeval notime; 4724265Ssklower 4824265Ssklower if (argc < 2) { 4924265Ssklower printf("usage: query hosts...\n"); 5024265Ssklower exit(1); 5124265Ssklower } 5224265Ssklower s = getsocket(SOCK_DGRAM, 0); 5324265Ssklower if (s < 0) { 5424265Ssklower perror("socket"); 5524265Ssklower exit(2); 5624265Ssklower } 5724265Ssklower 5824265Ssklower argv++, argc--; 5924326Ssklower query(argv,argc); 6024265Ssklower 6124265Ssklower /* 6224265Ssklower * Listen for returning packets; 6324265Ssklower * may be more than one packet per host. 6424265Ssklower */ 6524265Ssklower bits = 1 << s; 6624265Ssklower bzero(¬ime, sizeof(notime)); 6724265Ssklower signal(SIGALRM, timeout); 6824265Ssklower alarm(WTIME); 6924326Ssklower while (!timedout || 7024265Ssklower select(20, &bits, 0, 0, ¬ime) > 0) { 7124265Ssklower struct nspacket { 7224265Ssklower struct idp hdr; 7324265Ssklower char data[512]; 7424265Ssklower } response; 7524265Ssklower cc = recvfrom(s, &response, sizeof (response), 0, 7624265Ssklower &from, &fromlen); 7724265Ssklower if (cc <= 0) { 7824265Ssklower if (cc < 0) { 7924265Ssklower if (errno == EINTR) 8024265Ssklower continue; 8124265Ssklower perror("recvfrom"); 8224265Ssklower (void) close(s); 8324265Ssklower exit(1); 8424265Ssklower } 8524265Ssklower continue; 8624265Ssklower } 8724265Ssklower rip_input(&from, response.data, cc); 8824265Ssklower count--; 8924265Ssklower } 9024265Ssklower } 91*26176Ssklower static struct sockaddr_ns router = {AF_NS}; 92*26176Ssklower static struct ns_addr zero_addr; 93*26176Ssklower static short allones[] = {-1, -1, -1}; 9424265Ssklower 9524326Ssklower query(argv,argc) 9624326Ssklower char **argv; 9724265Ssklower { 9824265Ssklower register struct rip *msg = (struct rip *)packet; 9924326Ssklower char *host = *argv; 100*26176Ssklower struct ns_addr specific; 10124265Ssklower 10224326Ssklower argv++; argc--; 103*26176Ssklower router.sns_addr = ns_addr(host); 10424265Ssklower router.sns_addr.x_port = htons(IDPPORT_RIF); 105*26176Ssklower if (ns_hosteq(zero_addr, router.sns_addr)) { 106*26176Ssklower router.sns_addr.x_host = *(union ns_host *) allones; 107*26176Ssklower } 10824265Ssklower msg->rip_cmd = htons(RIPCMD_REQUEST); 109*26176Ssklower msg->rip_nets[0].rip_dst = *(union ns_net *) allones; 11024265Ssklower msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 11124326Ssklower if (argc > 0) { 112*26176Ssklower specific = ns_addr(*argv); 113*26176Ssklower msg->rip_nets[0].rip_dst = specific.x_net; 114*26176Ssklower specific.x_host = zero_addr.x_host; 115*26176Ssklower specific.x_port = zero_addr.x_port; 116*26176Ssklower printf("Net asked for was %s\n", ns_ntoa(specific)); 11724326Ssklower } 11824265Ssklower if (sendto(s, packet, sizeof (struct rip), 0, 11924265Ssklower &router, sizeof(router)) < 0) 12024265Ssklower perror(host); 12124265Ssklower } 12224265Ssklower 12324265Ssklower /* 12424265Ssklower * Handle an incoming routing packet. 12524265Ssklower */ 12624265Ssklower rip_input(from, msg, size) 12724265Ssklower struct sockaddr_ns *from; 12824265Ssklower register struct rip *msg; 12924265Ssklower int size; 13024265Ssklower { 13124265Ssklower struct netinfo *n; 13224265Ssklower char *name; 13324265Ssklower int lna, net, subnet; 13424265Ssklower struct hostent *hp; 13524265Ssklower struct netent *np; 136*26176Ssklower static struct ns_addr work; 13724265Ssklower 13824265Ssklower if (htons(msg->rip_cmd) != RIPCMD_RESPONSE) 13924265Ssklower return; 140*26176Ssklower printf("from %s\n", ns_ntoa(from->sns_addr)); 14124265Ssklower size -= sizeof (struct idp); 14224265Ssklower size -= sizeof (short); 14324265Ssklower n = msg->rip_nets; 14424265Ssklower while (size > 0) { 145*26176Ssklower union ns_net_u net; 14624265Ssklower if (size < sizeof (struct netinfo)) 14724265Ssklower break; 148*26176Ssklower net.net_e = n->rip_dst; 149*26176Ssklower printf("\t%d, metric %d\n", ntohl(net.long_e), 15024265Ssklower ntohs(n->rip_metric)); 15124265Ssklower size -= sizeof (struct netinfo), n++; 15224265Ssklower } 15324265Ssklower } 15424265Ssklower 15524265Ssklower timeout() 15624265Ssklower { 15724265Ssklower timedout = 1; 15824265Ssklower } 15924265Ssklower getsocket(type, proto) 16024265Ssklower int type, proto; 16124265Ssklower { 16224265Ssklower struct sockaddr_ns *sns = &myaddr; 16324265Ssklower int domain = sns->sns_family; 16424265Ssklower int retry, s, on = 1; 16524265Ssklower 16624265Ssklower retry = 1; 16724265Ssklower while ((s = socket(domain, type, proto)) < 0 && retry) { 16824265Ssklower perror("socket"); 16924265Ssklower sleep(5 * retry); 17024265Ssklower retry <<= 1; 17124265Ssklower } 17224265Ssklower if (retry == 0) 17324265Ssklower return (-1); 17424265Ssklower while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { 17524265Ssklower perror("bind"); 17624265Ssklower sleep(5 * retry); 17724265Ssklower retry <<= 1; 17824265Ssklower } 17924265Ssklower if (retry == 0) 18024265Ssklower return (-1); 18124265Ssklower if (domain==AF_NS) { 18224265Ssklower struct idp idp; 18324265Ssklower if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 18424265Ssklower perror("setsockopt SEE HEADERS"); 18524265Ssklower exit(1); 18624265Ssklower } 18724265Ssklower idp.idp_pt = NSPROTO_RI; 18824265Ssklower if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { 18924265Ssklower perror("setsockopt SET HEADERS"); 19024265Ssklower exit(1); 19124265Ssklower } 19224265Ssklower } 19324265Ssklower if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 19424265Ssklower perror("setsockopt SO_BROADCAST"); 19524265Ssklower exit(1); 19624265Ssklower } 19724265Ssklower return (s); 19824265Ssklower } 199