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