diff options
Diffstat (limited to 'contrib/traceroute/findsaddr-mib.c')
-rw-r--r-- | contrib/traceroute/findsaddr-mib.c | 378 |
1 files changed, 0 insertions, 378 deletions
diff --git a/contrib/traceroute/findsaddr-mib.c b/contrib/traceroute/findsaddr-mib.c deleted file mode 100644 index e5fc1d7..0000000 --- a/contrib/traceroute/findsaddr-mib.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2000 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Seriously complex Solaris mib2 code */ - -#ifndef lint -static const char rcsid[] = - "@(#) $Id: findsaddr-mib.c,v 1.2 2000/12/13 21:31:49 leres Exp $ (LBL)"; -#endif - -#include <sys/param.h> -#include <sys/file.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#ifdef HAVE_SYS_SOCKIO_H -#include <sys/sockio.h> -#endif -#include <sys/time.h> /* concession to AIX */ -#include <sys/stream.h> -#include <sys/tihdr.h> -#include <sys/tiuser.h> - -#if __STDC__ -struct mbuf; -struct rtentry; -#endif - -#include <net/if.h> -#include <net/route.h> - -#include <netinet/in.h> - -#include <inet/common.h> -#include <inet/mib2.h> -#include <inet/ip.h> -#include <inet/arp.h> - -#include <arpa/inet.h> - -#include <errno.h> -#include <fcntl.h> -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stropts.h> -#include <unistd.h> - -#include "gnuc.h" -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#include "findsaddr.h" - -/* Compatibility with older versions of Solaris */ -#ifndef IRE_CACHE -#define IRE_CACHE IRE_ROUTE -#endif - -#ifndef T_CURRENT -#define T_CURRENT MI_T_CURRENT -#endif - -struct routelist { - struct routelist *next; - u_int32_t dest; - u_int32_t mask; - u_int32_t gate; - char ifname[64]; -}; - -/* Forwards */ -static struct routelist *getroutelist(char *); -static void freeroutelist(struct routelist *); - -/* - * Return the source address for the given destination address - * - * Since solaris doesn't report the interface associated with every - * route, we have to make two passes over the routing table. The - * first pass should yield a host, net, default or interface route. - * If we find an interface route we're done. If not, we need to - * make a second pass to find the interface route for the gateway - * in the host, net, default route we found in the first pass. - * - * So instead of making a single pass through the tables as they - * are retrieved from the kernel, we must build a linked list... - */ -const char * -findsaddr(register const struct sockaddr_in *to, - register struct sockaddr_in *from) -{ - register struct routelist *rl, *rl2, *routelist; - static char errbuf[512]; - u_int32_t mask, gate; - - /* Get the routing table */ - routelist = getroutelist(errbuf); - if (routelist == NULL) - return (errbuf); - - /* First pass; look for a route that matches */ - mask = 0; - rl2 = NULL; - for (rl = routelist; rl != NULL; rl = rl->next) { - if ((to->sin_addr.s_addr & rl->mask) == rl->dest && - (rl->mask > mask || mask == 0) && - rl->gate != 0) { - mask = rl->mask; - rl2 = rl; - } - } - if (rl2 == NULL) { - freeroutelist(routelist); - sprintf(errbuf, "%s: %.128s", - inet_ntoa(to->sin_addr), strerror(EHOSTUNREACH)); - return (errbuf); - } - - /* We're done if we got one with an interface */ - if (rl2->ifname[0] != '\0') { - freeroutelist(routelist); - from->sin_addr.s_addr = rl2->gate; - return (NULL); - } - - /* First pass; look for a route that matches the gateway we found */ - mask = 0; - gate = rl2->gate; - rl2 = NULL; - for (rl = routelist; rl != NULL; rl = rl->next) { - if ((gate & rl->mask) == rl->dest && - (rl->mask > mask || mask == 0) && - rl->gate != 0 && - rl->ifname[0] != '\0') { - mask = rl->mask; - rl2 = rl; - } - } - if (rl2 == NULL) { - freeroutelist(routelist); - sprintf(errbuf, "%s: %.128s (second pass)", - inet_ntoa(to->sin_addr), strerror(EHOSTUNREACH)); - return (errbuf); - } - - from->sin_addr.s_addr = rl2->gate; - freeroutelist(routelist); - return (NULL); -} - -/* Request mib */ -struct mibrq { - struct T_optmgmt_req req; - struct opthdr hdr; -}; - -/* Reply mib */ -struct mibrep { - struct T_optmgmt_ack ack; - struct opthdr hdr; - char buf[512]; -}; - -static struct mibrq mibrq = { - { T_OPTMGMT_REQ, sizeof(mibrq.hdr), sizeof(mibrq.req), T_CURRENT }, - { MIB2_IP } -}; - -static struct mibrep mibrep = { - { 0, 0, 0 }, - { 0 }, - { 0 } -}; - -static struct strbuf rqbuf = { - 0, sizeof(mibrq), (char *)&mibrq -}; - -static struct strbuf repbuf = { - sizeof(mibrep.buf), sizeof(mibrep.ack) + sizeof(mibrep.hdr), - (char *)&mibrep -}; - -static const char devip[] = "/dev/ip"; - -/* - * Construct the list of routes - */ -static struct routelist * -getroutelist(char *errbuf) -{ - register int s, stat, i; - register char *cp; - register struct T_optmgmt_ack *ackp; - register struct T_error_ack *eackp; - register struct opthdr *hp; - register mib2_ipRouteEntry_t *rp, *rp2; - register struct routelist *rl, *rl2, *routelist; - int flags; - struct strbuf repbuf2; - - s = open(devip, O_RDWR, 0); - if (s < 0) { - sprintf(errbuf, "open %s: %.128s", devip, strerror(errno)); - return (NULL); - } - - if ((cp = "arp", ioctl(s, I_PUSH, cp) < 0) || - (cp = "tcp", ioctl(s, I_PUSH, cp) < 0) || - (cp = "udp", ioctl(s, I_PUSH, cp) < 0)) { - sprintf(errbuf, "I_PUSH %s: %.128s", cp, strerror(errno)); - close(s); - return (NULL); - } - - flags = 0; - if (putmsg(s, &rqbuf, NULL, flags) < 0) { - sprintf(errbuf, "putmsg: %.128s", strerror(errno)); - close(s); - return (NULL); - } - - routelist= NULL; - rl2 = NULL; - - rp = NULL; - - ackp = &mibrep.ack; - hp = &mibrep.hdr; - eackp = (struct T_error_ack *)ackp; - for (;;) { - flags = 0; - memset(repbuf.buf, 0, repbuf.len); - stat = getmsg(s, &repbuf, NULL, &flags); - if (stat < 0) { - sprintf(errbuf, "getmsg: %.128s", strerror(errno)); - goto bail; - } - if (stat == 0 && repbuf.len >= sizeof(*ackp) && - ackp->PRIM_type == T_OPTMGMT_ACK && - ackp->MGMT_flags == T_SUCCESS && - hp->len == 0) { - /* All done! */ - goto done; - } - if (repbuf.len >= sizeof(*eackp) && - eackp->PRIM_type == T_ERROR_ACK) { - sprintf(errbuf, "getmsg err: %.128s", - strerror((eackp->TLI_error == TSYSERR) ? - eackp->UNIX_error : EPROTO)); - goto bail; - } - if (stat != MOREDATA || - repbuf.len < sizeof(*ackp) || - ackp->PRIM_type != T_OPTMGMT_ACK || - ackp->MGMT_flags != T_SUCCESS) { - strcpy(errbuf, "unknown getmsg err"); - goto bail; - } - - memset(&repbuf2, 0, sizeof(repbuf2)); - repbuf2.maxlen = hp->len; - rp = malloc(hp->len); - if (rp == NULL) { - sprintf(errbuf, "malloc: %.128s", strerror(errno)); - goto bail; - } - repbuf2.buf = (char *)rp; - - flags = 0; - memset(repbuf2.buf, 0, repbuf2.len); - stat = getmsg(s, NULL, &repbuf2, &flags); - if (stat < 0) { - sprintf(errbuf, "getmsg2: %.128s", strerror(errno)); - goto bail; - } - - /* Spin through the routes */ - rp2 = rp; - for (rp2 = rp; (char *)rp2 < (char *)rp + repbuf2.len; ++rp2) { - if (hp->level != MIB2_IP || hp->name != MIB2_IP_21) - continue; - - if (rp2->ipRouteInfo.re_ire_type == IRE_CACHE || - rp2->ipRouteInfo.re_ire_type == IRE_BROADCAST) - continue; - - /* Got one we want to keep */ - rl = malloc(sizeof(*rl)); - if (rl == NULL) { - sprintf(errbuf, - "malloc 2: %.128s", strerror(errno)); - goto bail; - } - memset(rl, 0, sizeof(*rl)); - - rl->mask = rp2->ipRouteMask; - rl->dest = rp2->ipRouteDest; - rl->gate = rp2->ipRouteNextHop; - if (rp2->ipRouteIfIndex.o_length > 0) { - i = rp2->ipRouteIfIndex.o_length; - if (i > sizeof(rl->ifname) - 1) - i = sizeof(rl->ifname) - 1; - strncpy(rl->ifname, - rp2->ipRouteIfIndex.o_bytes, i); - rl->ifname[i] = '\0'; - } - - /* Keep in order (just for fun) */ - if (routelist == NULL) - routelist = rl; - if (rl2 != NULL) - rl2->next = rl; - rl2 = rl; - } - free(rp); - rp = NULL; - } - - strcpy(errbuf, "failed!"); - -bail: - if (routelist != NULL) { - freeroutelist(routelist); - routelist = NULL; - } -done: - if (rp != NULL) - free(rp); - close(s); - return (routelist); -} - -static void -freeroutelist(register struct routelist *rl) -{ - register struct routelist *rl2; - - while (rl != NULL) { - rl2 = rl->next; - free(rl); - rl = rl2; - } -} |