diff options
author | Bill Fenner <fenner@FreeBSD.org> | 1999-01-20 07:44:18 +0000 |
---|---|---|
committer | Bill Fenner <fenner@FreeBSD.org> | 1999-01-20 07:44:18 +0000 |
commit | 1f25327484733d0bec3b33044da7bd5d82ad007f (patch) | |
tree | 19c94eeb7ba2b59b0ad53ae0864ebf06723a8afa /usr.sbin/mrouted/ipip.c | |
parent | ce595def0708b60ce4dde9002ac206fae20be240 (diff) |
Import mrouted version 3.9-beta3+IOS12 . This is a version of 3.9-beta3vendor/mrouted
with minor changes to work around a bug in Cisco's IOS version 12.0 .
3.9-beta3 is much improved over 3.8, and is only labelled "beta" because
of missing features, as opposed to instability or known bugs.
Notes
Notes:
svn path=/cvs2svn/branches/XEROX/; revision=42888
Diffstat (limited to 'usr.sbin/mrouted/ipip.c')
-rw-r--r-- | usr.sbin/mrouted/ipip.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/usr.sbin/mrouted/ipip.c b/usr.sbin/mrouted/ipip.c new file mode 100644 index 000000000000..6e88d932d3b4 --- /dev/null +++ b/usr.sbin/mrouted/ipip.c @@ -0,0 +1,145 @@ +/* + * The mrouted program is covered by the license in the accompanying file + * named "LICENSE". Use of the mrouted program represents acceptance of + * the terms and conditions listed in that file. + * + * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of + * Leland Stanford Junior University. + * + * + * ipip.c,v 3.8.4.6 1998/01/06 01:57:45 fenner Exp + */ + + +#include "defs.h" + +#ifndef lint +static char rcsid[] = "@(#) $Id: \ +ipip.c,v 3.8.4.6 1998/01/06 01:57:45 fenner Exp $"; +#endif + +/* + * Exported variables. + */ +#ifdef notyet +int raw_socket; /* socket for raw network I/O */ +#endif +/* + *XXX For now, we just use the IGMP socket to send packets. + * This is legal in BSD, because the protocol # is not checked + * on raw sockets. The k_* interfaces need to gain a socket + * argument so that we can call them on the raw_socket also. + */ +#define raw_socket igmp_socket + +/* + * Private variables. + */ +static int rawid = 0; + +/* + * Open and initialize the raw socket. + */ +void +init_ipip() +{ +#ifdef notyet + if ((raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) + log(LOG_ERR, errno, "Raw IP socket"); +#endif +} + +/* + * Allocate and fill in static IP header for encapsulating on a tunnel. + */ +void +init_ipip_on_vif(v) + struct uvif *v; +{ + struct ip *ip; + + ip = v->uv_encap_hdr = (struct ip *)malloc(sizeof(struct ip)); + if (ip == NULL) + log(LOG_ERR, 0, "out of memory"); + bzero(ip, sizeof(struct ip)); + /* + * Fields zeroed that aren't filled in later: + * - IP ID (let the kernel fill it in) + * - Offset (we don't send fragments) + * - Checksum (let the kernel fill it in) + */ + ip->ip_v = IPVERSION; + ip->ip_hl = sizeof(struct ip) >> 2; + ip->ip_tos = 0xc0; /* Internet Control */ + ip->ip_ttl = MAXTTL; /* applies to unicasts only */ + ip->ip_p = IPPROTO_IPIP; + ip->ip_src.s_addr = v->uv_lcl_addr; + ip->ip_dst.s_addr = v->uv_rmt_addr; +} + +/* + * Call build_igmp() to build an IGMP message in the output packet buffer. + * Then fill in the fields of the IP packet that build_igmp() left for the + * kernel to fill in, and encapsulate the original packet with the + * pre-created ip header for this vif. + */ +void +send_ipip(src, dst, type, code, group, datalen, v) + u_int32 src, dst; + int type, code; + u_int32 group; + int datalen; + struct uvif *v; +{ + struct msghdr msg; + struct iovec iov[2]; + struct sockaddr_in sdst; + struct ip *ip; + + build_igmp(src, dst, type, code, group, datalen); + ip = (struct ip *)send_buf; +#ifndef RAW_OUTPUT_IS_RAW + ip->ip_len = htons(ip->ip_len); +#endif + ip->ip_id = htons(rawid++); + ip->ip_sum = 0; + ip->ip_sum = inet_cksum((u_short *)ip, ip->ip_hl << 2); + + ip = v->uv_encap_hdr; + ip->ip_len = 2 * MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen; +#ifdef RAW_OUTPUT_IS_RAW + ip->ip_len = htons(ip->ip_len); +#endif + + bzero(&sdst, sizeof(sdst)); + sdst.sin_family = AF_INET; +#ifdef HAVE_SA_LEN + sdst.sin_len = sizeof(sdst); +#endif + sdst.sin_addr = ip->ip_dst; + + iov[0].iov_base = (caddr_t)v->uv_encap_hdr; + iov[0].iov_len = sizeof(struct ip); + iov[1].iov_base = (caddr_t)send_buf; + iov[1].iov_len = MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen; + + bzero(&msg, sizeof(msg)); + msg.msg_name = (caddr_t)&sdst; + msg.msg_namelen = sizeof(sdst); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + if (sendmsg(raw_socket, &msg, 0) < 0) { + if (errno == ENETDOWN) + check_vif_state(); + else + log(LOG_WARNING, errno, + "sendmsg to %s on %s", + inet_fmt(sdst.sin_addr.s_addr, s1), inet_fmt(src, s2)); + } + + IF_DEBUG(DEBUG_PKT|igmp_debug_kind(type, code)) + log(LOG_DEBUG, 0, "SENT %s from %-15s to %s encaped to %s", + igmp_packet_kind(type, code), src == INADDR_ANY ? "INADDR_ANY" : + inet_fmt(src, s1), inet_fmt(dst, s2), + inet_fmt(sdst.sin_addr.s_addr, s3)); +} |