1: /* 2: * Copyright (c) 1983, 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * This file include significant work done at Cornell University 7: * by Bill Nesheim. That work included by permission. 8: */ 9: 10: #ifndef lint 11: char copyright[] = 12: "@(#) Copyright (c) 1983, 1986 Regents of the University of California.\n\ 13: All rights reserved.\n"; 14: #endif not lint 15: 16: #ifndef lint 17: static char sccsid[] = "@(#)query.c 1.4 (Berkeley) 2/14/86"; 18: #endif not lint 19: 20: #include <sys/param.h> 21: #include <sys/protosw.h> 22: #include <sys/socket.h> 23: #include <sys/time.h> 24: #include <netinet/in.h> 25: #include <netns/ns.h> 26: #include <netns/idp.h> 27: #include <errno.h> 28: #include <stdio.h> 29: #include <netdb.h> 30: #include "../protocol.h" 31: #define IDPPORT_RIF 1 32: 33: #define WTIME 5 /* Time to wait for responses */ 34: 35: int s; 36: int timedout, timeout(); 37: char packet[MAXPACKETSIZE]; 38: extern int errno; 39: struct sockaddr_ns myaddr = {AF_NS}; 40: char ns_ntoa(); 41: struct ns_addr ns_addr(); 42: main(argc, argv) 43: int argc; 44: char *argv[]; 45: { 46: int cc, count, bits; 47: struct sockaddr from; 48: int fromlen = sizeof(from); 49: struct timeval notime; 50: 51: if (argc < 2) { 52: printf("usage: query hosts...\n"); 53: exit(1); 54: } 55: s = getsocket(SOCK_DGRAM, 0); 56: if (s < 0) { 57: perror("socket"); 58: exit(2); 59: } 60: 61: argv++, argc--; 62: query(argv,argc); 63: 64: /* 65: * Listen for returning packets; 66: * may be more than one packet per host. 67: */ 68: bits = 1 << s; 69: bzero(¬ime, sizeof(notime)); 70: signal(SIGALRM, timeout); 71: alarm(WTIME); 72: while (!timedout || 73: select(20, &bits, 0, 0, ¬ime) > 0) { 74: struct nspacket { 75: struct idp hdr; 76: char data[512]; 77: } response; 78: cc = recvfrom(s, &response, sizeof (response), 0, 79: &from, &fromlen); 80: if (cc <= 0) { 81: if (cc < 0) { 82: if (errno == EINTR) 83: continue; 84: perror("recvfrom"); 85: (void) close(s); 86: exit(1); 87: } 88: continue; 89: } 90: rip_input(&from, response.data, cc); 91: count--; 92: } 93: } 94: static struct sockaddr_ns router = {AF_NS}; 95: static struct ns_addr zero_addr; 96: static short allones[] = {-1, -1, -1}; 97: 98: query(argv,argc) 99: char **argv; 100: { 101: register struct rip *msg = (struct rip *)packet; 102: char *host = *argv; 103: struct ns_addr specific; 104: 105: argv++; argc--; 106: router.sns_addr = ns_addr(host); 107: router.sns_addr.x_port = htons(IDPPORT_RIF); 108: if (ns_hosteq(zero_addr, router.sns_addr)) { 109: router.sns_addr.x_host = *(union ns_host *) allones; 110: } 111: msg->rip_cmd = htons(RIPCMD_REQUEST); 112: msg->rip_nets[0].rip_dst = *(union ns_net *) allones; 113: msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 114: if (argc > 0) { 115: specific = ns_addr(*argv); 116: msg->rip_nets[0].rip_dst = specific.x_net; 117: specific.x_host = zero_addr.x_host; 118: specific.x_port = zero_addr.x_port; 119: printf("Net asked for was %s\n", ns_ntoa(specific)); 120: } 121: if (sendto(s, packet, sizeof (struct rip), 0, 122: &router, sizeof(router)) < 0) 123: perror(host); 124: } 125: 126: /* 127: * Handle an incoming routing packet. 128: */ 129: rip_input(from, msg, size) 130: struct sockaddr_ns *from; 131: register struct rip *msg; 132: int size; 133: { 134: struct netinfo *n; 135: char *name; 136: int lna, net, subnet; 137: struct hostent *hp; 138: struct netent *np; 139: static struct ns_addr work; 140: 141: if (htons(msg->rip_cmd) != RIPCMD_RESPONSE) 142: return; 143: printf("from %s\n", ns_ntoa(from->sns_addr)); 144: size -= sizeof (struct idp); 145: size -= sizeof (short); 146: n = msg->rip_nets; 147: while (size > 0) { 148: union ns_net_u net; 149: if (size < sizeof (struct netinfo)) 150: break; 151: net.net_e = n->rip_dst; 152: printf("\t%d, metric %d\n", ntohl(net.long_e), 153: ntohs(n->rip_metric)); 154: size -= sizeof (struct netinfo), n++; 155: } 156: } 157: 158: timeout() 159: { 160: timedout = 1; 161: } 162: getsocket(type, proto) 163: int type, proto; 164: { 165: struct sockaddr_ns *sns = &myaddr; 166: int domain = sns->sns_family; 167: int retry, s, on = 1; 168: 169: retry = 1; 170: while ((s = socket(domain, type, proto)) < 0 && retry) { 171: perror("socket"); 172: sleep(5 * retry); 173: retry <<= 1; 174: } 175: if (retry == 0) 176: return (-1); 177: while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { 178: perror("bind"); 179: sleep(5 * retry); 180: retry <<= 1; 181: } 182: if (retry == 0) 183: return (-1); 184: if (domain==AF_NS) { 185: struct idp idp; 186: if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 187: perror("setsockopt SEE HEADERS"); 188: exit(1); 189: } 190: idp.idp_pt = NSPROTO_RI; 191: if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { 192: perror("setsockopt SET HEADERS"); 193: exit(1); 194: } 195: } 196: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 197: perror("setsockopt SO_BROADCAST"); 198: exit(1); 199: } 200: return (s); 201: }