summaryrefslogtreecommitdiffstats
path: root/contrib/traceroute/findsaddr-mib.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/traceroute/findsaddr-mib.c')
-rw-r--r--contrib/traceroute/findsaddr-mib.c378
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;
- }
-}
OpenPOWER on IntegriCloud