diff options
author | fenner <fenner@FreeBSD.org> | 1996-01-19 01:28:30 +0000 |
---|---|---|
committer | fenner <fenner@FreeBSD.org> | 1996-01-19 01:28:30 +0000 |
commit | 83b323c8bd36c10521fce66c79e1ddb594f4712c (patch) | |
tree | f8b6f3734f60d2c5f2bb7741981ab064e8950cad | |
parent | d9db1417ad554db7cbc6c29b834e17727da14c4c (diff) | |
download | FreeBSD-src-83b323c8bd36c10521fce66c79e1ddb594f4712c.zip FreeBSD-src-83b323c8bd36c10521fce66c79e1ddb594f4712c.tar.gz |
Made router discovery at least build and run. There are a few things
left to do (e.g. it doesn't yet run on systems with aliased addresses)
but this should work for simple configurations.
I don't plan to enable the rdisc directory in the sbin/ makefile until
I get feedback on this and add the missing features, so please, if you
have routers that perform router discovery, or if your FreeBSD box is
itself a router, give this a try.
-rw-r--r-- | sbin/rdisc/Makefile | 8 | ||||
-rw-r--r-- | sbin/rdisc/rdisc.c | 110 | ||||
-rw-r--r-- | sbin/rdisc/rdisc.h | 19 |
3 files changed, 81 insertions, 56 deletions
diff --git a/sbin/rdisc/Makefile b/sbin/rdisc/Makefile new file mode 100644 index 0000000..a3cf031 --- /dev/null +++ b/sbin/rdisc/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 6/5/93 + +PROG= rdisc +MAN8= rdisc.8 +BINOWN= root +BINMODE=555 + +.include <bsd.prog.mk> diff --git a/sbin/rdisc/rdisc.c b/sbin/rdisc/rdisc.c index 6f057b3..ca2b1c6 100644 --- a/sbin/rdisc/rdisc.c +++ b/sbin/rdisc/rdisc.c @@ -43,14 +43,6 @@ #include <netinet/ip.h> #include <netinet/ip_icmp.h> -/* - * The next include contains all defs and structures for multicast - * that are not in SunOS 4.1.x. On a SunOS 4.1.x system none of this code - * is ever used because it does not support multicast - * Fraser Gardiner - Sun Microsystems Australia - */ - -#include "rdisc.h" #include <netdb.h> #include <arpa/inet.h> @@ -96,21 +88,6 @@ static int join(); #define MAXIFS 32 -/* For router advertisement */ -struct icmp_ra { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - u_char icmp_num_addrs; - u_char icmp_wpa; /* Words per address */ - short icmp_lifetime; -}; - -struct icmp_ra_addr { - u_long addr; - u_long preference; -}; - /* Router constants */ #define MAX_INITIAL_ADVERT_INTERVAL 16 #define MAX_INITIAL_ADVERTISEMENTS 3 @@ -517,7 +494,7 @@ advertise(sin) struct sockaddr_in *sin; { static u_char outpack[MAXPACKET]; - register struct icmp_ra *rap = (struct icmp_ra *) ALLIGN(outpack); + register struct icmp *rap = (struct icmp *) ALLIGN(outpack); struct icmp_ra_addr *ap; int packetlen, i, cc; @@ -541,8 +518,8 @@ advertise(sin) * each address.) */ ap = (struct icmp_ra_addr *)ALLIGN(outpack + ICMP_MINLEN); - ap->addr = interfaces[i].localaddr.s_addr; - ap->preference = interfaces[i].preference; + ap->ira_addr = interfaces[i].localaddr.s_addr; + ap->ira_preference = interfaces[i].preference; packetlen += rap->icmp_wpa * 4; rap->icmp_num_addrs++; @@ -681,7 +658,7 @@ struct sockaddr_in *from; } switch (icp->icmp_type) { case ICMP_ROUTER_ADVERTISEMENT: { - struct icmp_ra *rap = (struct icmp_ra *)ALLIGN(icp); + struct icmp *rap = (struct icmp *)ALLIGN(icp); struct icmp_ra_addr *ap; if (responder) @@ -736,6 +713,7 @@ struct sockaddr_in *from; rap->icmp_num_addrs * rap->icmp_wpa * 4); return; } + rap->icmp_lifetime = ntohs(rap->icmp_lifetime); if (rap->icmp_lifetime < 4) { if (verbose) logtrace("ICMP %s from %s: Lifetime = %d\n", @@ -758,15 +736,15 @@ struct sockaddr_in *from; ap = (struct icmp_ra_addr *) ALLIGN(buf + hlen + ICMP_MINLEN + i * rap->icmp_wpa * 4); - ina.s_addr = ntohl(ap->addr); + ina.s_addr = ap->ira_addr; if (verbose) logtrace("\taddress %s, preference 0x%x\n", pr_name(ina), - ntohl(ap->preference)); + ntohl(ap->ira_preference)); if (!responder) { if (is_directly_connected(ina)) record_router(ina, - (long)ntohl(ap->preference), + (long)ntohl(ap->ira_preference), rap->icmp_lifetime); } } @@ -988,7 +966,7 @@ isbroadcast(sin) ismulticast(sin) struct sockaddr_in *sin; { - return (IN_CLASSD(sin->sin_addr.s_addr)); + return (IN_CLASSD(ntohl(sin->sin_addr.s_addr))); } /* From libc/rpc/pmap_rmt.c */ @@ -1114,7 +1092,7 @@ initifs() { int sock; struct ifconf ifc; - struct ifreq ifreq, *ifr; + struct ifreq ifreq, *ifrp, *ifend; struct sockaddr_in *sin; int n, i; char *buf; @@ -1140,6 +1118,7 @@ initifs() (void) close(sock); return; } + bzero(buf, bufsize); if (interfaces) interfaces = (struct interface *)ALLIGN(realloc((char *)interfaces, numifs * sizeof(struct interface))); @@ -1162,14 +1141,18 @@ initifs() (void) free(buf); return; } - ifr = ifc.ifc_req; - for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) { - ifreq = *ifr; + ifrp = (struct ifreq *)buf; + ifend = (struct ifreq *)(buf + ifc.ifc_len); + for (i = 0; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) { + ifreq = *ifrp; if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { logperror("initifs: ioctl (get interface flags)"); continue; } - if (ifr->ifr_addr.sa_family != AF_INET) + n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); + if (n < sizeof(*ifrp)) + n = sizeof(*ifrp); + if (ifrp->ifr_addr.sa_family != AF_INET) continue; if ((ifreq.ifr_flags & IFF_UP) == 0) continue; @@ -1177,7 +1160,7 @@ initifs() continue; if ((ifreq.ifr_flags & (IFF_MULTICAST | IFF_BROADCAST)) == 0) continue; - sin = (struct sockaddr_in *)ALLIGN(&ifr->ifr_addr); + sin = (struct sockaddr_in *)ALLIGN(&ifrp->ifr_addr); interfaces[i].localaddr = sin->sin_addr; interfaces[i].flags = ifreq.ifr_flags; interfaces[i].netmask.s_addr = (unsigned long)0xffffffff; @@ -1461,7 +1444,11 @@ add_route(addr) { if (debug) logdebug("Add default route to %s\n", pr_name(addr)); +#if 1 + rtioctl(addr, RTM_ADD); +#else rtioctl(addr, SIOCADDRT); +#endif } void @@ -1470,7 +1457,11 @@ del_route(addr) { if (debug) logdebug("Delete default route to %s\n", pr_name(addr)); +#if 1 + rtioctl(addr, RTM_DELETE); +#else rtioctl(addr, SIOCDELRT); +#endif } void @@ -1479,7 +1470,48 @@ rtioctl(addr, op) int op; { int sock; +#if 1 + struct { + struct rt_msghdr m_rtm; + struct sockaddr_in m_dst; + struct sockaddr_in m_gateway; + struct sockaddr_in m_netmask; + } m_rtmsg; + static int seq = 0; + + bzero(&m_rtmsg, sizeof(m_rtmsg)); +#define rtm m_rtmsg.m_rtm + rtm.rtm_type = op; + rtm.rtm_flags = RTF_GATEWAY | RTF_UP; /* XXX more? */ + rtm.rtm_version = RTM_VERSION; + rtm.rtm_seq = ++seq; + rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; + bzero(&rtm.rtm_rmx, sizeof(rtm.rtm_rmx)); /* XXX ??? */ + rtm.rtm_inits = 0; + rtm.rtm_msglen = sizeof(m_rtmsg); + + m_rtmsg.m_dst.sin_len = m_rtmsg.m_gateway.sin_len = + sizeof(struct sockaddr_in); + m_rtmsg.m_netmask.sin_len = 0; + m_rtmsg.m_dst.sin_family = m_rtmsg.m_gateway.sin_family = + m_rtmsg.m_netmask.sin_family = AF_INET; + m_rtmsg.m_dst.sin_addr.s_addr = 0; /* default */ + m_rtmsg.m_netmask.sin_addr.s_addr = 0; /* default */ + m_rtmsg.m_gateway.sin_addr = addr; /* gateway */ + + sock = socket(PF_ROUTE, SOCK_RAW, 0); + if (sock < 0) { + logperror("rtioctl: socket"); + return; + } + if (write(sock, &m_rtmsg, sizeof(m_rtmsg)) != sizeof(m_rtmsg)) { + logperror("rtioctl: write"); + return; + } + close(sock); +#else struct rtentry rt; + struct sockaddr_in *sin; bzero((char *)&rt, sizeof(struct rtentry)); rt.rt_dst.sa_family = AF_INET; @@ -1498,6 +1530,7 @@ rtioctl(addr, op) logperror("ioctl (add/delete route)"); } (void) close(sock); +#endif } @@ -1549,7 +1582,10 @@ logdebug(fmt, a,b,c,d,e,f,g,h) (void) fprintf(stdout, fmt, a,b,c,d,e,f,g,h); } +#if 0 extern char *sys_errlist[]; +#endif + extern int errno; void diff --git a/sbin/rdisc/rdisc.h b/sbin/rdisc/rdisc.h deleted file mode 100644 index 507c9ce..0000000 --- a/sbin/rdisc/rdisc.h +++ /dev/null @@ -1,19 +0,0 @@ -/* From net/if.h */ - -#define IFF_MULTICAST 0x800 /* supports multicast */ - -/* From netinet/in.h */ - -#define INADDR_ALLHOSTS_GROUP (u_long)0xe0000001 /* 224.0.0.1 */ -#define IP_MULTICAST_IF 0x10 /* set/get IP multicast interface */ -#define IP_ADD_MEMBERSHIP 0x13 /* add an IP group membership */ -#define IP_MULTICAST_TTL 0x11 /* set/get IP multicast timetolive */ - -/* - * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. - */ -struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -}; - |