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.
6 * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
7 * Leland Stanford Junior University.
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 $
20 int raw_socket; /* socket for raw network I/O */
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.
28 #define raw_socket igmp_socket
36 * Open and initialize the raw socket.
42 if ((raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
43 log(LOG_ERR, errno, "Raw IP socket");
48 * Allocate and fill in static IP header for encapsulating on a tunnel.
56 ip = v->uv_encap_hdr = (struct ip *)malloc(sizeof(struct ip));
58 log(LOG_ERR, 0, "out of memory");
59 bzero(ip, sizeof(struct ip));
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)
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;
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.
82 send_ipip(src, dst, type, code, group, datalen, v)
91 struct sockaddr_in sdst;
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);
99 ip->ip_id = htons(rawid++);
101 ip->ip_sum = inet_cksum((u_short *)ip, ip->ip_hl << 2);
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);
109 bzero(&sdst, sizeof(sdst));
110 sdst.sin_family = AF_INET;
112 sdst.sin_len = sizeof(sdst);
114 sdst.sin_addr = ip->ip_dst;
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;
121 bzero(&msg, sizeof(msg));
122 msg.msg_name = (caddr_t)&sdst;
123 msg.msg_namelen = sizeof(sdst);
126 if (sendmsg(raw_socket, &msg, 0) < 0) {
127 if (errno == ENETDOWN)
130 log(LOG_WARNING, errno,
131 "sendmsg to %s on %s",
132 inet_fmt(sdst.sin_addr.s_addr, s1), inet_fmt(src, s2));
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));