1*48127Sbostic /*- 235547Sbostic * Copyright (c) 1983, 1986 The Regents of the University of California. 335547Sbostic * All rights reserved. 426177Ssklower * 5*48127Sbostic * This code includes software contributed to Berkeley by 6*48127Sbostic * Bill Nesheim at Cornell University. 735547Sbostic * 8*48127Sbostic * %sccs.include.redist.c% 924265Ssklower */ 1024265Ssklower 1124265Ssklower #ifndef lint 1224326Ssklower char copyright[] = 1335547Sbostic "@(#) Copyright (c) 1983, 1986 The Regents of the University of California.\n\ 1424326Ssklower All rights reserved.\n"; 1535547Sbostic #endif /* not lint */ 1624265Ssklower 1724326Ssklower #ifndef lint 18*48127Sbostic static char sccsid[] = "@(#)query.c 5.8 (Berkeley) 04/16/91"; 1935547Sbostic #endif /* not lint */ 2024326Ssklower 2124265Ssklower #include <sys/param.h> 2224265Ssklower #include <sys/protosw.h> 2324265Ssklower #include <sys/socket.h> 2424265Ssklower #include <sys/time.h> 2524265Ssklower #include <netinet/in.h> 2624265Ssklower #include <netns/ns.h> 2724265Ssklower #include <netns/idp.h> 2824265Ssklower #include <errno.h> 2924265Ssklower #include <stdio.h> 3024265Ssklower #include <netdb.h> 3124265Ssklower #include "../protocol.h" 3224265Ssklower #define IDPPORT_RIF 1 3324265Ssklower 3424265Ssklower #define WTIME 5 /* Time to wait for responses */ 3524265Ssklower 3624265Ssklower int s; 3724265Ssklower int timedout, timeout(); 3824265Ssklower char packet[MAXPACKETSIZE]; 3924265Ssklower extern int errno; 4045667Ssklower struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS}; 4130814Sbostic char *ns_ntoa(); 4226176Ssklower struct ns_addr ns_addr(); 4324265Ssklower main(argc, argv) 4424265Ssklower int argc; 4524265Ssklower char *argv[]; 4624265Ssklower { 4724265Ssklower int cc, count, bits; 4824265Ssklower struct sockaddr from; 4924265Ssklower int fromlen = sizeof(from); 5024265Ssklower struct timeval notime; 5124265Ssklower 5224265Ssklower if (argc < 2) { 5324265Ssklower printf("usage: query hosts...\n"); 5424265Ssklower exit(1); 5524265Ssklower } 5624265Ssklower s = getsocket(SOCK_DGRAM, 0); 5724265Ssklower if (s < 0) { 5824265Ssklower perror("socket"); 5924265Ssklower exit(2); 6024265Ssklower } 6124265Ssklower 6224265Ssklower argv++, argc--; 6324326Ssklower query(argv,argc); 6424265Ssklower 6524265Ssklower /* 6624265Ssklower * Listen for returning packets; 6724265Ssklower * may be more than one packet per host. 6824265Ssklower */ 6924265Ssklower bits = 1 << s; 7024265Ssklower bzero(¬ime, sizeof(notime)); 7124265Ssklower signal(SIGALRM, timeout); 7224265Ssklower alarm(WTIME); 7324326Ssklower while (!timedout || 7424265Ssklower select(20, &bits, 0, 0, ¬ime) > 0) { 7524265Ssklower struct nspacket { 7624265Ssklower struct idp hdr; 7724265Ssklower char data[512]; 7824265Ssklower } response; 7924265Ssklower cc = recvfrom(s, &response, sizeof (response), 0, 8024265Ssklower &from, &fromlen); 8124265Ssklower if (cc <= 0) { 8224265Ssklower if (cc < 0) { 8324265Ssklower if (errno == EINTR) 8424265Ssklower continue; 8524265Ssklower perror("recvfrom"); 8624265Ssklower (void) close(s); 8724265Ssklower exit(1); 8824265Ssklower } 8924265Ssklower continue; 9024265Ssklower } 9124265Ssklower rip_input(&from, response.data, cc); 9224265Ssklower count--; 9324265Ssklower } 9424265Ssklower } 9545667Ssklower static struct sockaddr_ns router = {sizeof(myaddr), AF_NS}; 9626176Ssklower static struct ns_addr zero_addr; 9726176Ssklower static short allones[] = {-1, -1, -1}; 9824265Ssklower 9924326Ssklower query(argv,argc) 10024326Ssklower char **argv; 10124265Ssklower { 10224265Ssklower register struct rip *msg = (struct rip *)packet; 10324326Ssklower char *host = *argv; 10445667Ssklower int flags = 0; 10526176Ssklower struct ns_addr specific; 10624265Ssklower 10745667Ssklower if (bcmp(*argv, "-r", 3) == 0) { 10845667Ssklower flags = MSG_DONTROUTE; argv++; argc--; 10945667Ssklower } 11045667Ssklower host = *argv; 11126176Ssklower router.sns_addr = ns_addr(host); 11224265Ssklower router.sns_addr.x_port = htons(IDPPORT_RIF); 11326176Ssklower if (ns_hosteq(zero_addr, router.sns_addr)) { 11426176Ssklower router.sns_addr.x_host = *(union ns_host *) allones; 11526176Ssklower } 11624265Ssklower msg->rip_cmd = htons(RIPCMD_REQUEST); 11726176Ssklower msg->rip_nets[0].rip_dst = *(union ns_net *) allones; 11824265Ssklower msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 11924326Ssklower if (argc > 0) { 12026176Ssklower specific = ns_addr(*argv); 12126176Ssklower msg->rip_nets[0].rip_dst = specific.x_net; 12226176Ssklower specific.x_host = zero_addr.x_host; 12326176Ssklower specific.x_port = zero_addr.x_port; 12426176Ssklower printf("Net asked for was %s\n", ns_ntoa(specific)); 12524326Ssklower } 12645667Ssklower if (sendto(s, packet, sizeof (struct rip), flags, 12724265Ssklower &router, sizeof(router)) < 0) 12824265Ssklower perror(host); 12924265Ssklower } 13024265Ssklower 13124265Ssklower /* 13224265Ssklower * Handle an incoming routing packet. 13324265Ssklower */ 13424265Ssklower rip_input(from, msg, size) 13524265Ssklower struct sockaddr_ns *from; 13624265Ssklower register struct rip *msg; 13724265Ssklower int size; 13824265Ssklower { 13924265Ssklower struct netinfo *n; 14024265Ssklower char *name; 14124265Ssklower int lna, net, subnet; 14224265Ssklower struct hostent *hp; 14324265Ssklower struct netent *np; 14426176Ssklower static struct ns_addr work; 14524265Ssklower 14624265Ssklower if (htons(msg->rip_cmd) != RIPCMD_RESPONSE) 14724265Ssklower return; 14826176Ssklower printf("from %s\n", ns_ntoa(from->sns_addr)); 14924265Ssklower size -= sizeof (struct idp); 15024265Ssklower size -= sizeof (short); 15124265Ssklower n = msg->rip_nets; 15224265Ssklower while (size > 0) { 15326176Ssklower union ns_net_u net; 15424265Ssklower if (size < sizeof (struct netinfo)) 15524265Ssklower break; 15626176Ssklower net.net_e = n->rip_dst; 15726176Ssklower printf("\t%d, metric %d\n", ntohl(net.long_e), 15824265Ssklower ntohs(n->rip_metric)); 15924265Ssklower size -= sizeof (struct netinfo), n++; 16024265Ssklower } 16124265Ssklower } 16224265Ssklower 16324265Ssklower timeout() 16424265Ssklower { 16524265Ssklower timedout = 1; 16624265Ssklower } 16724265Ssklower getsocket(type, proto) 16824265Ssklower int type, proto; 16924265Ssklower { 17024265Ssklower struct sockaddr_ns *sns = &myaddr; 17124265Ssklower int domain = sns->sns_family; 17224265Ssklower int retry, s, on = 1; 17324265Ssklower 17424265Ssklower retry = 1; 17524265Ssklower while ((s = socket(domain, type, proto)) < 0 && retry) { 17624265Ssklower perror("socket"); 17724265Ssklower sleep(5 * retry); 17824265Ssklower retry <<= 1; 17924265Ssklower } 18024265Ssklower if (retry == 0) 18124265Ssklower return (-1); 18224265Ssklower while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { 18324265Ssklower perror("bind"); 18424265Ssklower sleep(5 * retry); 18524265Ssklower retry <<= 1; 18624265Ssklower } 18724265Ssklower if (retry == 0) 18824265Ssklower return (-1); 18924265Ssklower if (domain==AF_NS) { 19024265Ssklower struct idp idp; 19124265Ssklower if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 19224265Ssklower perror("setsockopt SEE HEADERS"); 19324265Ssklower exit(1); 19424265Ssklower } 19524265Ssklower idp.idp_pt = NSPROTO_RI; 19624265Ssklower if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { 19724265Ssklower perror("setsockopt SET HEADERS"); 19824265Ssklower exit(1); 19924265Ssklower } 20024265Ssklower } 20124265Ssklower if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 20224265Ssklower perror("setsockopt SO_BROADCAST"); 20324265Ssklower exit(1); 20424265Ssklower } 20524265Ssklower return (s); 20624265Ssklower } 207