124265Ssklower /* 2*24326Ssklower * 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 8*24326Ssklower char copyright[] = 9*24326Ssklower "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*24326Ssklower All rights reserved.\n"; 1124265Ssklower #endif not lint 1224265Ssklower 13*24326Ssklower #ifndef lint 14*24326Ssklower static char sccsid[] = "@(#)query.c 5.2 (Berkeley) 08/16/85"; 15*24326Ssklower #endif not lint 16*24326Ssklower 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 #define xnnet(p) (*(long *)&(p)) 3024265Ssklower 3124265Ssklower #define WTIME 5 /* Time to wait for responses */ 3224265Ssklower 3324265Ssklower int s; 3424265Ssklower int timedout, timeout(); 3524265Ssklower char packet[MAXPACKETSIZE]; 3624265Ssklower extern int errno; 3724265Ssklower struct sockaddr_ns myaddr = {AF_NS}; 3824265Ssklower main(argc, argv) 3924265Ssklower int argc; 4024265Ssklower char *argv[]; 4124265Ssklower { 4224265Ssklower int cc, count, bits; 4324265Ssklower struct sockaddr from; 4424265Ssklower int fromlen = sizeof(from); 4524265Ssklower struct timeval notime; 4624265Ssklower 4724265Ssklower if (argc < 2) { 4824265Ssklower printf("usage: query hosts...\n"); 4924265Ssklower exit(1); 5024265Ssklower } 5124265Ssklower s = getsocket(SOCK_DGRAM, 0); 5224265Ssklower if (s < 0) { 5324265Ssklower perror("socket"); 5424265Ssklower exit(2); 5524265Ssklower } 5624265Ssklower 5724265Ssklower argv++, argc--; 58*24326Ssklower query(argv,argc); 5924265Ssklower 6024265Ssklower /* 6124265Ssklower * Listen for returning packets; 6224265Ssklower * may be more than one packet per host. 6324265Ssklower */ 6424265Ssklower bits = 1 << s; 6524265Ssklower bzero(¬ime, sizeof(notime)); 6624265Ssklower signal(SIGALRM, timeout); 6724265Ssklower alarm(WTIME); 68*24326Ssklower while (!timedout || 6924265Ssklower select(20, &bits, 0, 0, ¬ime) > 0) { 7024265Ssklower struct nspacket { 7124265Ssklower struct idp hdr; 7224265Ssklower char data[512]; 7324265Ssklower } response; 7424265Ssklower cc = recvfrom(s, &response, sizeof (response), 0, 7524265Ssklower &from, &fromlen); 7624265Ssklower if (cc <= 0) { 7724265Ssklower if (cc < 0) { 7824265Ssklower if (errno == EINTR) 7924265Ssklower continue; 8024265Ssklower perror("recvfrom"); 8124265Ssklower (void) close(s); 8224265Ssklower exit(1); 8324265Ssklower } 8424265Ssklower continue; 8524265Ssklower } 8624265Ssklower rip_input(&from, response.data, cc); 8724265Ssklower count--; 8824265Ssklower } 8924265Ssklower } 9024265Ssklower 91*24326Ssklower query(argv,argc) 92*24326Ssklower char **argv; 9324265Ssklower { 9424265Ssklower struct sockaddr_ns router; 9524265Ssklower register struct rip *msg = (struct rip *)packet; 9624265Ssklower long mynet; 9724265Ssklower short work[3]; 98*24326Ssklower char *host = *argv; 9924265Ssklower 100*24326Ssklower argv++; argc--; 10124265Ssklower bzero((char *)&router, sizeof (router)); 10224265Ssklower router.sns_family = AF_NS; 10324265Ssklower router.sns_addr.x_port = htons(IDPPORT_RIF); 10424265Ssklower sscanf(host, "%ld:%hx,%hx,%hx", 10524265Ssklower &mynet,work+0, work+1, work+2); 10624265Ssklower router.sns_addr.x_host = *(union ns_host *)work; 10724265Ssklower xnnet(router.sns_addr.x_net) = htonl(mynet); 10824265Ssklower msg->rip_cmd = htons(RIPCMD_REQUEST); 10924265Ssklower xnnet(msg->rip_nets[0]) = -1; 11024265Ssklower msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 111*24326Ssklower if (argc > 0) { 112*24326Ssklower u_long wanted = xnnet(msg->rip_nets[0]) = htonl(atoi(*argv)); 113*24326Ssklower printf("Net asked for was %d\n", ntohl(wanted)); 114*24326Ssklower } 11524265Ssklower if (sendto(s, packet, sizeof (struct rip), 0, 11624265Ssklower &router, sizeof(router)) < 0) 11724265Ssklower perror(host); 11824265Ssklower } 11924265Ssklower 12024265Ssklower /* 12124265Ssklower * Handle an incoming routing packet. 12224265Ssklower */ 12324265Ssklower rip_input(from, msg, size) 12424265Ssklower struct sockaddr_ns *from; 12524265Ssklower register struct rip *msg; 12624265Ssklower int size; 12724265Ssklower { 12824265Ssklower struct netinfo *n; 12924265Ssklower char *name; 13024265Ssklower int lna, net, subnet; 13124265Ssklower struct hostent *hp; 13224265Ssklower struct netent *np; 13324265Ssklower 13424265Ssklower if (htons(msg->rip_cmd) != RIPCMD_RESPONSE) 13524265Ssklower return; 13624265Ssklower printf("from %d:%x,%x,%x\n", 13724265Ssklower ntohl(xnnet(from->sns_addr.x_net)), 13824265Ssklower from->sns_addr.x_host.s_host[0], 13924265Ssklower from->sns_addr.x_host.s_host[1], 14024265Ssklower from->sns_addr.x_host.s_host[2]); 14124265Ssklower size -= sizeof (struct idp); 14224265Ssklower size -= sizeof (short); 14324265Ssklower n = msg->rip_nets; 14424265Ssklower while (size > 0) { 14524265Ssklower if (size < sizeof (struct netinfo)) 14624265Ssklower break; 14724265Ssklower printf("\t%d, metric %d\n", ntohl(xnnet(n->rip_dst[0])), 14824265Ssklower ntohs(n->rip_metric)); 14924265Ssklower size -= sizeof (struct netinfo), n++; 15024265Ssklower } 15124265Ssklower } 15224265Ssklower 15324265Ssklower timeout() 15424265Ssklower { 15524265Ssklower timedout = 1; 15624265Ssklower } 15724265Ssklower getsocket(type, proto) 15824265Ssklower int type, proto; 15924265Ssklower { 16024265Ssklower struct sockaddr_ns *sns = &myaddr; 16124265Ssklower int domain = sns->sns_family; 16224265Ssklower int retry, s, on = 1; 16324265Ssklower 16424265Ssklower retry = 1; 16524265Ssklower while ((s = socket(domain, type, proto)) < 0 && retry) { 16624265Ssklower perror("socket"); 16724265Ssklower sleep(5 * retry); 16824265Ssklower retry <<= 1; 16924265Ssklower } 17024265Ssklower if (retry == 0) 17124265Ssklower return (-1); 17224265Ssklower while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { 17324265Ssklower perror("bind"); 17424265Ssklower sleep(5 * retry); 17524265Ssklower retry <<= 1; 17624265Ssklower } 17724265Ssklower if (retry == 0) 17824265Ssklower return (-1); 17924265Ssklower if (domain==AF_NS) { 18024265Ssklower struct idp idp; 18124265Ssklower if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 18224265Ssklower perror("setsockopt SEE HEADERS"); 18324265Ssklower exit(1); 18424265Ssklower } 18524265Ssklower idp.idp_pt = NSPROTO_RI; 18624265Ssklower if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { 18724265Ssklower perror("setsockopt SET HEADERS"); 18824265Ssklower exit(1); 18924265Ssklower } 19024265Ssklower } 19124265Ssklower if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 19224265Ssklower perror("setsockopt SO_BROADCAST"); 19324265Ssklower exit(1); 19424265Ssklower } 19524265Ssklower return (s); 19624265Ssklower } 197