124265Ssklower /* 2*35547Sbostic * Copyright (c) 1983, 1986 The Regents of the University of California. 3*35547Sbostic * All rights reserved. 426177Ssklower * 5*35547Sbostic * This file includes significant work done at Cornell University by 6*35547Sbostic * Bill Nesheim. That work included by permission. 7*35547Sbostic * 8*35547Sbostic * Redistribution and use in source and binary forms are permitted 9*35547Sbostic * provided that the above copyright notice and this paragraph are 10*35547Sbostic * duplicated in all such forms and that any documentation, 11*35547Sbostic * advertising materials, and other materials related to such 12*35547Sbostic * distribution and use acknowledge that the software was developed 13*35547Sbostic * by the University of California, Berkeley. The name of the 14*35547Sbostic * University may not be used to endorse or promote products derived 15*35547Sbostic * from this software without specific prior written permission. 16*35547Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*35547Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*35547Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1924265Ssklower */ 2024265Ssklower 2124265Ssklower #ifndef lint 2224326Ssklower char copyright[] = 23*35547Sbostic "@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\ 2424326Ssklower All rights reserved.\n"; 25*35547Sbostic #endif /* not lint */ 2624265Ssklower 2724326Ssklower #ifndef lint 28*35547Sbostic static char sccsid[] = "@(#)query.c 5.6 (Berkeley) 09/19/88"; 29*35547Sbostic #endif /* not lint */ 3024326Ssklower 3124265Ssklower #include <sys/param.h> 3224265Ssklower #include <sys/protosw.h> 3324265Ssklower #include <sys/socket.h> 3424265Ssklower #include <sys/time.h> 3524265Ssklower #include <netinet/in.h> 3624265Ssklower #include <netns/ns.h> 3724265Ssklower #include <netns/idp.h> 3824265Ssklower #include <errno.h> 3924265Ssklower #include <stdio.h> 4024265Ssklower #include <netdb.h> 4124265Ssklower #include "../protocol.h" 4224265Ssklower #define IDPPORT_RIF 1 4324265Ssklower 4424265Ssklower #define WTIME 5 /* Time to wait for responses */ 4524265Ssklower 4624265Ssklower int s; 4724265Ssklower int timedout, timeout(); 4824265Ssklower char packet[MAXPACKETSIZE]; 4924265Ssklower extern int errno; 5024265Ssklower struct sockaddr_ns myaddr = {AF_NS}; 5130814Sbostic char *ns_ntoa(); 5226176Ssklower struct ns_addr ns_addr(); 5324265Ssklower main(argc, argv) 5424265Ssklower int argc; 5524265Ssklower char *argv[]; 5624265Ssklower { 5724265Ssklower int cc, count, bits; 5824265Ssklower struct sockaddr from; 5924265Ssklower int fromlen = sizeof(from); 6024265Ssklower struct timeval notime; 6124265Ssklower 6224265Ssklower if (argc < 2) { 6324265Ssklower printf("usage: query hosts...\n"); 6424265Ssklower exit(1); 6524265Ssklower } 6624265Ssklower s = getsocket(SOCK_DGRAM, 0); 6724265Ssklower if (s < 0) { 6824265Ssklower perror("socket"); 6924265Ssklower exit(2); 7024265Ssklower } 7124265Ssklower 7224265Ssklower argv++, argc--; 7324326Ssklower query(argv,argc); 7424265Ssklower 7524265Ssklower /* 7624265Ssklower * Listen for returning packets; 7724265Ssklower * may be more than one packet per host. 7824265Ssklower */ 7924265Ssklower bits = 1 << s; 8024265Ssklower bzero(¬ime, sizeof(notime)); 8124265Ssklower signal(SIGALRM, timeout); 8224265Ssklower alarm(WTIME); 8324326Ssklower while (!timedout || 8424265Ssklower select(20, &bits, 0, 0, ¬ime) > 0) { 8524265Ssklower struct nspacket { 8624265Ssklower struct idp hdr; 8724265Ssklower char data[512]; 8824265Ssklower } response; 8924265Ssklower cc = recvfrom(s, &response, sizeof (response), 0, 9024265Ssklower &from, &fromlen); 9124265Ssklower if (cc <= 0) { 9224265Ssklower if (cc < 0) { 9324265Ssklower if (errno == EINTR) 9424265Ssklower continue; 9524265Ssklower perror("recvfrom"); 9624265Ssklower (void) close(s); 9724265Ssklower exit(1); 9824265Ssklower } 9924265Ssklower continue; 10024265Ssklower } 10124265Ssklower rip_input(&from, response.data, cc); 10224265Ssklower count--; 10324265Ssklower } 10424265Ssklower } 10526176Ssklower static struct sockaddr_ns router = {AF_NS}; 10626176Ssklower static struct ns_addr zero_addr; 10726176Ssklower static short allones[] = {-1, -1, -1}; 10824265Ssklower 10924326Ssklower query(argv,argc) 11024326Ssklower char **argv; 11124265Ssklower { 11224265Ssklower register struct rip *msg = (struct rip *)packet; 11324326Ssklower char *host = *argv; 11426176Ssklower struct ns_addr specific; 11524265Ssklower 11624326Ssklower argv++; argc--; 11726176Ssklower router.sns_addr = ns_addr(host); 11824265Ssklower router.sns_addr.x_port = htons(IDPPORT_RIF); 11926176Ssklower if (ns_hosteq(zero_addr, router.sns_addr)) { 12026176Ssklower router.sns_addr.x_host = *(union ns_host *) allones; 12126176Ssklower } 12224265Ssklower msg->rip_cmd = htons(RIPCMD_REQUEST); 12326176Ssklower msg->rip_nets[0].rip_dst = *(union ns_net *) allones; 12424265Ssklower msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 12524326Ssklower if (argc > 0) { 12626176Ssklower specific = ns_addr(*argv); 12726176Ssklower msg->rip_nets[0].rip_dst = specific.x_net; 12826176Ssklower specific.x_host = zero_addr.x_host; 12926176Ssklower specific.x_port = zero_addr.x_port; 13026176Ssklower printf("Net asked for was %s\n", ns_ntoa(specific)); 13124326Ssklower } 13224265Ssklower if (sendto(s, packet, sizeof (struct rip), 0, 13324265Ssklower &router, sizeof(router)) < 0) 13424265Ssklower perror(host); 13524265Ssklower } 13624265Ssklower 13724265Ssklower /* 13824265Ssklower * Handle an incoming routing packet. 13924265Ssklower */ 14024265Ssklower rip_input(from, msg, size) 14124265Ssklower struct sockaddr_ns *from; 14224265Ssklower register struct rip *msg; 14324265Ssklower int size; 14424265Ssklower { 14524265Ssklower struct netinfo *n; 14624265Ssklower char *name; 14724265Ssklower int lna, net, subnet; 14824265Ssklower struct hostent *hp; 14924265Ssklower struct netent *np; 15026176Ssklower static struct ns_addr work; 15124265Ssklower 15224265Ssklower if (htons(msg->rip_cmd) != RIPCMD_RESPONSE) 15324265Ssklower return; 15426176Ssklower printf("from %s\n", ns_ntoa(from->sns_addr)); 15524265Ssklower size -= sizeof (struct idp); 15624265Ssklower size -= sizeof (short); 15724265Ssklower n = msg->rip_nets; 15824265Ssklower while (size > 0) { 15926176Ssklower union ns_net_u net; 16024265Ssklower if (size < sizeof (struct netinfo)) 16124265Ssklower break; 16226176Ssklower net.net_e = n->rip_dst; 16326176Ssklower printf("\t%d, metric %d\n", ntohl(net.long_e), 16424265Ssklower ntohs(n->rip_metric)); 16524265Ssklower size -= sizeof (struct netinfo), n++; 16624265Ssklower } 16724265Ssklower } 16824265Ssklower 16924265Ssklower timeout() 17024265Ssklower { 17124265Ssklower timedout = 1; 17224265Ssklower } 17324265Ssklower getsocket(type, proto) 17424265Ssklower int type, proto; 17524265Ssklower { 17624265Ssklower struct sockaddr_ns *sns = &myaddr; 17724265Ssklower int domain = sns->sns_family; 17824265Ssklower int retry, s, on = 1; 17924265Ssklower 18024265Ssklower retry = 1; 18124265Ssklower while ((s = socket(domain, type, proto)) < 0 && retry) { 18224265Ssklower perror("socket"); 18324265Ssklower sleep(5 * retry); 18424265Ssklower retry <<= 1; 18524265Ssklower } 18624265Ssklower if (retry == 0) 18724265Ssklower return (-1); 18824265Ssklower while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { 18924265Ssklower perror("bind"); 19024265Ssklower sleep(5 * retry); 19124265Ssklower retry <<= 1; 19224265Ssklower } 19324265Ssklower if (retry == 0) 19424265Ssklower return (-1); 19524265Ssklower if (domain==AF_NS) { 19624265Ssklower struct idp idp; 19724265Ssklower if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 19824265Ssklower perror("setsockopt SEE HEADERS"); 19924265Ssklower exit(1); 20024265Ssklower } 20124265Ssklower idp.idp_pt = NSPROTO_RI; 20224265Ssklower if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { 20324265Ssklower perror("setsockopt SET HEADERS"); 20424265Ssklower exit(1); 20524265Ssklower } 20624265Ssklower } 20724265Ssklower if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 20824265Ssklower perror("setsockopt SO_BROADCAST"); 20924265Ssklower exit(1); 21024265Ssklower } 21124265Ssklower return (s); 21224265Ssklower } 213