This commit was generated by cvs2svn to compensate for changes in r42888,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
b8d4f311c5
1
usr.sbin/mrouted/VERSION
Normal file
1
usr.sbin/mrouted/VERSION
Normal file
@ -0,0 +1 @@
|
||||
3.9-beta3+IOS12
|
225
usr.sbin/mrouted/icmp.c
Normal file
225
usr.sbin/mrouted/icmp.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* icmp.c,v 3.8.4.2 1998/01/06 01:57:42 fenner Exp
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#) $Id: \
|
||||
icmp.c,v 3.8.4.2 1998/01/06 01:57:42 fenner Exp $";
|
||||
#endif
|
||||
|
||||
static int icmp_socket;
|
||||
|
||||
static void icmp_handler __P((int, fd_set *));
|
||||
static char * icmp_name __P((struct icmp *));
|
||||
|
||||
void
|
||||
init_icmp()
|
||||
{
|
||||
if ((icmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
||||
log(LOG_ERR, errno, "ICMP socket");
|
||||
|
||||
register_input_handler(icmp_socket, icmp_handler);
|
||||
|
||||
IF_DEBUG(DEBUG_ICMP)
|
||||
log(LOG_DEBUG, 0, "registering icmp socket fd %d\n", icmp_socket);
|
||||
}
|
||||
|
||||
static void
|
||||
icmp_handler(fd, rfds)
|
||||
int fd;
|
||||
fd_set *rfds;
|
||||
{
|
||||
u_char icmp_buf[RECV_BUF_SIZE];
|
||||
struct sockaddr_in from;
|
||||
int fromlen, recvlen, iphdrlen, ipdatalen;
|
||||
struct icmp *icmp;
|
||||
struct ip *ip;
|
||||
vifi_t i;
|
||||
struct uvif *v;
|
||||
u_int32 src;
|
||||
|
||||
fromlen = sizeof(from);
|
||||
recvlen = recvfrom(icmp_socket, icmp_buf, RECV_BUF_SIZE, 0,
|
||||
(struct sockaddr *)&from, &fromlen);
|
||||
if (recvlen < 0) {
|
||||
if (errno != EINTR)
|
||||
log(LOG_WARNING, errno, "icmp_socket recvfrom");
|
||||
return;
|
||||
}
|
||||
ip = (struct ip *)icmp_buf;
|
||||
iphdrlen = ip->ip_hl << 2;
|
||||
#ifdef RAW_INPUT_IS_RAW
|
||||
ipdatalen = ntohs(ip->ip_len) - iphdrlen;
|
||||
#else
|
||||
ipdatalen = ip->ip_len;
|
||||
#endif
|
||||
if (iphdrlen + ipdatalen != recvlen) {
|
||||
IF_DEBUG(DEBUG_ICMP)
|
||||
log(LOG_DEBUG, 0, "hdr %d data %d != rcv %d", iphdrlen, ipdatalen, recvlen);
|
||||
/* Malformed ICMP, just return. */
|
||||
return;
|
||||
}
|
||||
if (ipdatalen < ICMP_MINLEN + sizeof(struct ip)) {
|
||||
/* Not enough data for us to be interested in it. */
|
||||
return;
|
||||
}
|
||||
src = ip->ip_src.s_addr;
|
||||
icmp = (struct icmp *)(icmp_buf + iphdrlen);
|
||||
IF_DEBUG(DEBUG_ICMP)
|
||||
log(LOG_DEBUG, 0, "got ICMP type %d from %s",
|
||||
icmp->icmp_type, inet_fmt(src, s1));
|
||||
/*
|
||||
* Eventually:
|
||||
* have registry of ICMP listeners, by type, code and ICMP_ID
|
||||
* (and maybe fields of the original packet too -- maybe need a
|
||||
* generalized packet filter!) to allow ping and traceroute
|
||||
* from the monitoring tool.
|
||||
*/
|
||||
switch (icmp->icmp_type) {
|
||||
case ICMP_UNREACH:
|
||||
case ICMP_TIMXCEED:
|
||||
/* Look at returned packet to see if it's us sending on a tunnel */
|
||||
ip = &icmp->icmp_ip;
|
||||
if (ip->ip_p != IPPROTO_IGMP && ip->ip_p != IPPROTO_IPIP)
|
||||
return;
|
||||
for (v = uvifs, i = 0; i < numvifs; v++, i++) {
|
||||
if (ip->ip_src.s_addr == v->uv_lcl_addr &&
|
||||
ip->ip_dst.s_addr == v->uv_dst_addr) {
|
||||
char *p;
|
||||
int n;
|
||||
/*
|
||||
* I sent this packet on this vif.
|
||||
*/
|
||||
n = ++v->uv_icmp_warn;
|
||||
while (n && !(n & 1))
|
||||
n >>= 1;
|
||||
if (n == 1 && ((p = icmp_name(icmp)) != NULL))
|
||||
log(LOG_WARNING, 0, "Received ICMP %s from %s %s %s on vif %d",
|
||||
p, inet_fmt(src, s1), "for traffic sent to",
|
||||
inet_fmt(ip->ip_dst.s_addr, s2),
|
||||
i);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return NULL for ICMP informational messages.
|
||||
* Return string describing the error for ICMP errors.
|
||||
*/
|
||||
static char *
|
||||
icmp_name(icmp)
|
||||
struct icmp *icmp;
|
||||
{
|
||||
static char retval[30];
|
||||
|
||||
switch (icmp->icmp_type) {
|
||||
case ICMP_UNREACH:
|
||||
switch (icmp->icmp_code) {
|
||||
case ICMP_UNREACH_NET:
|
||||
return "network unreachable";
|
||||
case ICMP_UNREACH_HOST:
|
||||
return "host unreachable";
|
||||
case ICMP_UNREACH_PROTOCOL:
|
||||
return "protocol unreachable";
|
||||
case ICMP_UNREACH_PORT:
|
||||
return "port unreachable";
|
||||
case ICMP_UNREACH_NEEDFRAG:
|
||||
return "needs fragmentation";
|
||||
case ICMP_UNREACH_SRCFAIL:
|
||||
return "source route failed";
|
||||
#ifndef ICMP_UNREACH_NET_UNKNOWN
|
||||
#define ICMP_UNREACH_NET_UNKNOWN 6
|
||||
#endif
|
||||
case ICMP_UNREACH_NET_UNKNOWN:
|
||||
return "network unknown";
|
||||
#ifndef ICMP_UNREACH_HOST_UNKNOWN
|
||||
#define ICMP_UNREACH_HOST_UNKNOWN 7
|
||||
#endif
|
||||
case ICMP_UNREACH_HOST_UNKNOWN:
|
||||
return "host unknown";
|
||||
#ifndef ICMP_UNREACH_ISOLATED
|
||||
#define ICMP_UNREACH_ISOLATED 8
|
||||
#endif
|
||||
case ICMP_UNREACH_ISOLATED:
|
||||
return "source host isolated";
|
||||
#ifndef ICMP_UNREACH_NET_PROHIB
|
||||
#define ICMP_UNREACH_NET_PROHIB 9
|
||||
#endif
|
||||
case ICMP_UNREACH_NET_PROHIB:
|
||||
return "network access prohibited";
|
||||
#ifndef ICMP_UNREACH_HOST_PROHIB
|
||||
#define ICMP_UNREACH_HOST_PROHIB 10
|
||||
#endif
|
||||
case ICMP_UNREACH_HOST_PROHIB:
|
||||
return "host access prohibited";
|
||||
#ifndef ICMP_UNREACH_TOSNET
|
||||
#define ICMP_UNREACH_TOSNET 11
|
||||
#endif
|
||||
case ICMP_UNREACH_TOSNET:
|
||||
return "bad TOS for net";
|
||||
#ifndef ICMP_UNREACH_TOSHOST
|
||||
#define ICMP_UNREACH_TOSHOST 12
|
||||
#endif
|
||||
case ICMP_UNREACH_TOSHOST:
|
||||
return "bad TOS for host";
|
||||
#ifndef ICMP_UNREACH_FILTER_PROHIB
|
||||
#define ICMP_UNREACH_FILTER_PROHIB 13
|
||||
#endif
|
||||
case ICMP_UNREACH_FILTER_PROHIB:
|
||||
return "prohibited by filter";
|
||||
#ifndef ICMP_UNREACH_HOST_PRECEDENCE
|
||||
#define ICMP_UNREACH_HOST_PRECEDENCE 14
|
||||
#endif
|
||||
case ICMP_UNREACH_HOST_PRECEDENCE:
|
||||
return "host precedence violation";
|
||||
#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
|
||||
#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
|
||||
#endif
|
||||
case ICMP_UNREACH_PRECEDENCE_CUTOFF:
|
||||
return "precedence cutoff";
|
||||
default:
|
||||
sprintf(retval, "unreachable code %d", icmp->icmp_code);
|
||||
return retval;
|
||||
}
|
||||
case ICMP_SOURCEQUENCH:
|
||||
return "source quench";
|
||||
case ICMP_REDIRECT:
|
||||
return NULL; /* XXX */
|
||||
case ICMP_TIMXCEED:
|
||||
switch (icmp->icmp_code) {
|
||||
case ICMP_TIMXCEED_INTRANS:
|
||||
return "time exceeded in transit";
|
||||
case ICMP_TIMXCEED_REASS:
|
||||
return "time exceeded in reassembly";
|
||||
default:
|
||||
sprintf(retval, "time exceeded code %d", icmp->icmp_code);
|
||||
return retval;
|
||||
}
|
||||
case ICMP_PARAMPROB:
|
||||
switch (icmp->icmp_code) {
|
||||
#ifndef ICMP_PARAMPROB_OPTABSENT
|
||||
#define ICMP_PARAMPROB_OPTABSENT 1
|
||||
#endif
|
||||
case ICMP_PARAMPROB_OPTABSENT:
|
||||
return "required option absent";
|
||||
default:
|
||||
sprintf(retval, "parameter problem code %d", icmp->icmp_code);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
42
usr.sbin/mrouted/igmpv2.h
Normal file
42
usr.sbin/mrouted/igmpv2.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* igmpv2.h,v 3.8.4.1 1997/11/18 23:25:58 fenner Exp
|
||||
*/
|
||||
|
||||
/*
|
||||
* Constants for IGMP Version 2. Several of these, especially the
|
||||
* robustness variable, should be variables and not constants.
|
||||
*/
|
||||
#define IGMP_ROBUSTNESS_VARIABLE 2
|
||||
#define IGMP_QUERY_INTERVAL 125
|
||||
#define IGMP_QUERY_RESPONSE_INTERVAL 10
|
||||
#define IGMP_GROUP_MEMBERSHIP_INTERVAL (IGMP_ROBUSTNESS_VARIABLE * \
|
||||
IGMP_QUERY_INTERVAL + \
|
||||
IGMP_QUERY_RESPONSE_INTERVAL)
|
||||
#define IGMP_OTHER_QUERIER_PRESENT_INTERVAL (IGMP_ROBUSTNESS_VARIABLE * \
|
||||
IGMP_QUERY_INTERVAL + \
|
||||
IGMP_QUERY_RESPONSE_INTERVAL / 2)
|
||||
/* Round to the nearest TIMER_INTERVAL */
|
||||
#define IGMP_STARTUP_QUERY_INTERVAL (((IGMP_QUERY_INTERVAL / 4) \
|
||||
/ TIMER_INTERVAL) * TIMER_INTERVAL)
|
||||
#define IGMP_STARTUP_QUERY_COUNT IGMP_ROBUSTNESS_VARIABLE
|
||||
#define IGMP_LAST_MEMBER_QUERY_INTERVAL 1
|
||||
#define IGMP_LAST_MEMBER_QUERY_COUNT IGMP_ROBUSTNESS_VARIABLE
|
||||
|
||||
/*
|
||||
* OLD_AGE_THRESHOLD is the number of IGMP_QUERY_INTERVAL's to remember the
|
||||
* presence of an IGMPv1 group member. According to the IGMPv2 specification,
|
||||
* routers remember this presence for [Robustness Variable] * [Query Interval] +
|
||||
* [Query Response Interval]. However, OLD_AGE_THRESHOLD is in units of
|
||||
* [Query Interval], so doesn't have sufficient resolution to represent
|
||||
* [Query Response Interval]. When the timer mechanism gets an efficient
|
||||
* method of refreshing timers, this should get fixed.
|
||||
*/
|
||||
#define OLD_AGE_THRESHOLD IGMP_ROBUSTNESS_VARIABLE
|
145
usr.sbin/mrouted/ipip.c
Normal file
145
usr.sbin/mrouted/ipip.c
Normal file
@ -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));
|
||||
}
|
Loading…
Reference in New Issue
Block a user