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.3 2004/03/15 18:10:28 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.
51 init_ipip_on_vif(struct uvif
*v
)
55 ip
= v
->uv_encap_hdr
= (struct ip
*)malloc(sizeof(struct ip
));
57 log(LOG_ERR
, 0, "out of memory");
58 bzero(ip
, sizeof(struct ip
));
60 * Fields zeroed that aren't filled in later:
61 * - IP ID (let the kernel fill it in)
62 * - Offset (we don't send fragments)
63 * - Checksum (let the kernel fill it in)
66 ip
->ip_hl
= sizeof(struct ip
) >> 2;
67 ip
->ip_tos
= 0xc0; /* Internet Control */
68 ip
->ip_ttl
= MAXTTL
; /* applies to unicasts only */
69 ip
->ip_p
= IPPROTO_IPIP
;
70 ip
->ip_src
.s_addr
= v
->uv_lcl_addr
;
71 ip
->ip_dst
.s_addr
= v
->uv_rmt_addr
;
75 * Call build_igmp() to build an IGMP message in the output packet buffer.
76 * Then fill in the fields of the IP packet that build_igmp() left for the
77 * kernel to fill in, and encapsulate the original packet with the
78 * pre-created ip header for this vif.
81 send_ipip(u_int32 src
, u_int32 dst
, int type
, int code
, u_int32 group
,
82 int datalen
, struct uvif
*v
)
86 struct sockaddr_in sdst
;
89 build_igmp(src
, dst
, type
, code
, group
, datalen
);
90 ip
= (struct ip
*)send_buf
;
91 #ifndef RAW_OUTPUT_IS_RAW
92 ip
->ip_len
= htons(ip
->ip_len
);
94 ip
->ip_id
= htons(rawid
++);
96 ip
->ip_sum
= inet_cksum((u_short
*)ip
, ip
->ip_hl
<< 2);
99 ip
->ip_len
= 2 * MIN_IP_HEADER_LEN
+ IGMP_MINLEN
+ datalen
;
100 #ifdef RAW_OUTPUT_IS_RAW
101 ip
->ip_len
= htons(ip
->ip_len
);
104 bzero(&sdst
, sizeof(sdst
));
105 sdst
.sin_family
= AF_INET
;
107 sdst
.sin_len
= sizeof(sdst
);
109 sdst
.sin_addr
= ip
->ip_dst
;
111 iov
[0].iov_base
= (caddr_t
)v
->uv_encap_hdr
;
112 iov
[0].iov_len
= sizeof(struct ip
);
113 iov
[1].iov_base
= (caddr_t
)send_buf
;
114 iov
[1].iov_len
= MIN_IP_HEADER_LEN
+ IGMP_MINLEN
+ datalen
;
116 bzero(&msg
, sizeof(msg
));
117 msg
.msg_name
= (caddr_t
)&sdst
;
118 msg
.msg_namelen
= sizeof(sdst
);
121 if (sendmsg(raw_socket
, &msg
, 0) < 0) {
122 if (errno
== ENETDOWN
)
125 log(LOG_WARNING
, errno
,
126 "sendmsg to %s on %s",
127 inet_fmt(sdst
.sin_addr
.s_addr
, s1
), inet_fmt(src
, s2
));
130 IF_DEBUG(DEBUG_PKT
|igmp_debug_kind(type
, code
))
131 log(LOG_DEBUG
, 0, "SENT %s from %-15s to %s encaped to %s",
132 igmp_packet_kind(type
, code
), src
== INADDR_ANY
? "INADDR_ANY" :
133 inet_fmt(src
, s1
), inet_fmt(dst
, s2
),
134 inet_fmt(sdst
.sin_addr
.s_addr
, s3
));