]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/mrouted/ipip.c
This commit was generated by cvs2svn to compensate for changes in r97049,
[FreeBSD/FreeBSD.git] / usr.sbin / mrouted / ipip.c
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  * ipip.c,v 3.8.4.6 1998/01/06 01:57:45 fenner Exp
11  */
12
13
14 #include "defs.h"
15
16 #ifndef lint
17 static char rcsid[] = "@(#) $Id: \
18 ipip.c,v 3.8.4.6 1998/01/06 01:57:45 fenner Exp $";
19 #endif
20
21 /*
22  * Exported variables.
23  */
24 #ifdef notyet
25 int             raw_socket;                 /* socket for raw network I/O  */
26 #endif
27 /*
28  *XXX For now, we just use the IGMP socket to send packets.
29  * This is legal in BSD, because the protocol # is not checked
30  * on raw sockets.  The k_* interfaces need to gain a socket
31  * argument so that we can call them on the raw_socket also.
32  */
33 #define raw_socket      igmp_socket
34
35 /*
36  * Private variables.
37  */
38 static int rawid = 0;
39
40 /*
41  * Open and initialize the raw socket.
42  */
43 void
44 init_ipip()
45 {
46 #ifdef notyet
47     if ((raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
48         log(LOG_ERR, errno, "Raw IP socket");
49 #endif
50 }
51
52 /*
53  * Allocate and fill in static IP header for encapsulating on a tunnel.
54  */
55 void
56 init_ipip_on_vif(v)
57     struct uvif *v;
58 {
59     struct ip *ip;
60
61     ip = v->uv_encap_hdr = (struct ip *)malloc(sizeof(struct ip));
62     if (ip == NULL)
63         log(LOG_ERR, 0, "out of memory");
64     bzero(ip, sizeof(struct ip));
65     /*
66      * Fields zeroed that aren't filled in later:
67      * - IP ID (let the kernel fill it in)
68      * - Offset (we don't send fragments)
69      * - Checksum (let the kernel fill it in)
70      */
71     ip->ip_v   = IPVERSION;
72     ip->ip_hl  = sizeof(struct ip) >> 2;
73     ip->ip_tos = 0xc0;          /* Internet Control */
74     ip->ip_ttl = MAXTTL;        /* applies to unicasts only */
75     ip->ip_p   = IPPROTO_IPIP;
76     ip->ip_src.s_addr = v->uv_lcl_addr;
77     ip->ip_dst.s_addr = v->uv_rmt_addr;
78 }
79
80 /*
81  * Call build_igmp() to build an IGMP message in the output packet buffer.
82  * Then fill in the fields of the IP packet that build_igmp() left for the
83  * kernel to fill in, and encapsulate the original packet with the
84  * pre-created ip header for this vif.
85  */
86 void
87 send_ipip(src, dst, type, code, group, datalen, v)
88     u_int32 src, dst;
89     int type, code;
90     u_int32 group;
91     int datalen;
92     struct uvif *v;
93 {
94     struct msghdr msg;
95     struct iovec iov[2];
96     struct sockaddr_in sdst;
97     struct ip *ip;
98
99     build_igmp(src, dst, type, code, group, datalen);
100     ip = (struct ip *)send_buf;
101 #ifndef RAW_OUTPUT_IS_RAW
102     ip->ip_len = htons(ip->ip_len);
103 #endif
104     ip->ip_id = htons(rawid++);
105     ip->ip_sum = 0;
106     ip->ip_sum = inet_cksum((u_short *)ip, ip->ip_hl << 2);
107
108     ip = v->uv_encap_hdr;
109     ip->ip_len = 2 * MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen;
110 #ifdef RAW_OUTPUT_IS_RAW
111     ip->ip_len = htons(ip->ip_len);
112 #endif
113
114     bzero(&sdst, sizeof(sdst));
115     sdst.sin_family = AF_INET;
116 #ifdef HAVE_SA_LEN
117     sdst.sin_len = sizeof(sdst);
118 #endif
119     sdst.sin_addr = ip->ip_dst;
120
121     iov[0].iov_base = (caddr_t)v->uv_encap_hdr;
122     iov[0].iov_len = sizeof(struct ip);
123     iov[1].iov_base = (caddr_t)send_buf;
124     iov[1].iov_len = MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen;
125
126     bzero(&msg, sizeof(msg));
127     msg.msg_name = (caddr_t)&sdst;
128     msg.msg_namelen = sizeof(sdst);
129     msg.msg_iov = iov;
130     msg.msg_iovlen = 2;
131     if (sendmsg(raw_socket, &msg, 0) < 0) {
132         if (errno == ENETDOWN)
133             check_vif_state();
134         else
135             log(LOG_WARNING, errno,
136                 "sendmsg to %s on %s",
137                 inet_fmt(sdst.sin_addr.s_addr, s1), inet_fmt(src, s2));
138     }
139
140     IF_DEBUG(DEBUG_PKT|igmp_debug_kind(type, code))
141     log(LOG_DEBUG, 0, "SENT %s from %-15s to %s encaped to %s",
142         igmp_packet_kind(type, code), src == INADDR_ANY ? "INADDR_ANY" :
143                                  inet_fmt(src, s1), inet_fmt(dst, s2),
144                                  inet_fmt(sdst.sin_addr.s_addr, s3));
145 }