File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mrouted / ipip.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:10:48 2012 UTC (12 years, 4 months ago) by misho
Branches: mrouted, MAIN
CVS tags: v3_9_6p0, v3_9_6, v3_9_5, HEAD
mrouted

    1: /*
    2:  * The mrouted program is covered by the license in the accompanying file
    3:  * named "LICENSE".  Use of the mrouted program represents acceptance of
    4:  * the terms and conditions listed in that file.
    5:  *
    6:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
    7:  * Leland Stanford Junior University.
    8:  */
    9: 
   10: #include "defs.h"
   11: 
   12: /*
   13:  * Exported variables.
   14:  */
   15: #ifdef notyet
   16: int		raw_socket;		    /* socket for raw network I/O  */
   17: #endif
   18: /*
   19:  *XXX For now, we just use the IGMP socket to send packets.
   20:  * This is legal in BSD, because the protocol # is not checked
   21:  * on raw sockets.  The k_* interfaces need to gain a socket
   22:  * argument so that we can call them on the raw_socket also.
   23:  */
   24: #define	raw_socket	igmp_socket
   25: 
   26: /*
   27:  * Private variables.
   28:  */
   29: static int rawid = 0;
   30: 
   31: /*
   32:  * Open and initialize the raw socket.
   33:  */
   34: void init_ipip(void)
   35: {
   36: #ifdef notyet
   37:     if ((raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
   38: 	logit(LOG_ERR, errno, "Raw IP socket");
   39: #endif
   40: }
   41: 
   42: /*
   43:  * Allocate and fill in static IP header for encapsulating on a tunnel.
   44:  */
   45: void init_ipip_on_vif(struct uvif *v)
   46: {
   47:     struct ip *ip;
   48: 
   49:     ip = v->uv_encap_hdr = (struct ip *)malloc(sizeof(struct ip));
   50:     if (ip == NULL)
   51: 	logit(LOG_ERR, 0, "out of memory");
   52:     memset(ip, 0, sizeof(struct ip));
   53:     /*
   54:      * Fields zeroed that aren't filled in later:
   55:      * - IP ID (let the kernel fill it in)
   56:      * - Offset (we don't send fragments)
   57:      * - Checksum (let the kernel fill it in)
   58:      */
   59:     ip->ip_v   = IPVERSION;
   60:     ip->ip_hl  = sizeof(struct ip) >> 2;
   61:     ip->ip_tos = 0xc0;		/* Internet Control */
   62:     ip->ip_ttl = MAXTTL;	/* applies to unicasts only */
   63:     ip->ip_p   = IPPROTO_IPIP;
   64:     ip->ip_src.s_addr = v->uv_lcl_addr;
   65:     ip->ip_dst.s_addr = v->uv_rmt_addr;
   66: }
   67: 
   68: /*
   69:  * Call build_igmp() to build an IGMP message in the output packet buffer.
   70:  * Then fill in the fields of the IP packet that build_igmp() left for the
   71:  * kernel to fill in, and encapsulate the original packet with the
   72:  * pre-created ip header for this vif.
   73:  */
   74: void send_ipip(u_int32 src, u_int32 dst, int type, int code, u_int32 group, int datalen, struct uvif *v)
   75: {
   76:     struct msghdr msg;
   77:     struct iovec iov[2];
   78:     struct sockaddr_in sdst;
   79:     struct ip *ip;
   80: 
   81:     build_igmp(src, dst, type, code, group, datalen);
   82:     ip = (struct ip *)send_buf;
   83:     ip->ip_id = htons(rawid++);
   84:     ip->ip_sum = 0;
   85:     ip->ip_sum = inet_cksum((u_int16_t *)ip, ip->ip_hl << 2);
   86: 
   87:     ip = v->uv_encap_hdr;
   88:     ip->ip_len = 2 * MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen;
   89:     ip->ip_len = htons(ip->ip_len);
   90: 
   91:     memset(&sdst, 0, sizeof(sdst));
   92:     sdst.sin_family = AF_INET;
   93: #ifdef HAVE_SA_LEN
   94:     sdst.sin_len = sizeof(sdst);
   95: #endif
   96:     sdst.sin_addr = ip->ip_dst;
   97: 
   98:     iov[0].iov_base = (caddr_t)v->uv_encap_hdr;
   99:     iov[0].iov_len = sizeof(struct ip);
  100:     iov[1].iov_base = (caddr_t)send_buf;
  101:     iov[1].iov_len = MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen;
  102: 
  103:     memset(&msg, 0, sizeof(msg));
  104:     msg.msg_name = (caddr_t)&sdst;
  105:     msg.msg_namelen = sizeof(sdst);
  106:     msg.msg_iov = iov;
  107:     msg.msg_iovlen = 2;
  108:     if (sendmsg(raw_socket, &msg, 0) < 0) {
  109: 	if (errno == ENETDOWN)
  110: 	    check_vif_state();
  111: 	else
  112: 	    logit(LOG_WARNING, errno,
  113: 		"sendmsg to %s on %s",
  114: 		inet_fmt(sdst.sin_addr.s_addr, s1, sizeof(s1)), inet_fmt(src, s2, sizeof(s2)));
  115:     }
  116: 
  117:     IF_DEBUG(DEBUG_PKT|igmp_debug_kind(type, code))
  118:     logit(LOG_DEBUG, 0, "SENT %s from %-15s to %s encaped to %s",
  119: 	igmp_packet_kind(type, code), src == INADDR_ANY ? "INADDR_ANY" :
  120: 				 inet_fmt(src, s1, sizeof(s1)), inet_fmt(dst, s2, sizeof(s2)),
  121: 				 inet_fmt(sdst.sin_addr.s_addr, s3, sizeof(s3)));
  122: }
  123: 
  124: /**
  125:  * Local Variables:
  126:  *  version-control: t
  127:  *  indent-tabs-mode: t
  128:  *  c-file-style: "ellemtel"
  129:  *  c-basic-offset: 4
  130:  * End:
  131:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>