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