Annotation of embedaddon/bird/sysdep/bsd/sysio.h, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD Internet Routing Daemon -- BSD Multicasting and Network Includes
3: *
4: * (c) 2004 Ondrej Filip <feela@network.cz>
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: #include <net/if_dl.h>
10: #include <netinet/in_systm.h> // Workaround for some BSDs
11: #include <netinet/ip.h>
12:
13:
14: #ifdef __NetBSD__
15:
16: #ifndef IP_RECVTTL
17: #define IP_RECVTTL 23
18: #endif
19:
20: #ifndef IP_MINTTL
21: #define IP_MINTTL 24
22: #endif
23:
24: #endif
25:
26: #ifdef __DragonFly__
27: #define TCP_MD5SIG TCP_SIGNATURE_ENABLE
28: #endif
29:
30:
31: #undef SA_LEN
32: #define SA_LEN(x) (x).sa.sa_len
33:
34:
35: /*
36: * BSD IPv4 multicast syscalls
37: */
38:
39: #define INIT_MREQ4(maddr,ifa) \
40: { .imr_multiaddr = ipa_to_in4(maddr), .imr_interface = ipa_to_in4(ifa->addr->ip) }
41:
42: static inline int
43: sk_setup_multicast4(sock *s)
44: {
45: struct in_addr ifa = ipa_to_in4(s->iface->addr->ip);
46: u8 ttl = s->ttl;
47: u8 n = 0;
48:
49: /* This defines where should we send _outgoing_ multicasts */
50: if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_IF, &ifa, sizeof(ifa)) < 0)
51: ERR("IP_MULTICAST_IF");
52:
53: if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
54: ERR("IP_MULTICAST_TTL");
55:
56: if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &n, sizeof(n)) < 0)
57: ERR("IP_MULTICAST_LOOP");
58:
59: return 0;
60: }
61:
62: static inline int
63: sk_join_group4(sock *s, ip_addr maddr)
64: {
65: struct ip_mreq mr = INIT_MREQ4(maddr, s->iface);
66:
67: if (setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
68: ERR("IP_ADD_MEMBERSHIP");
69:
70: return 0;
71: }
72:
73: static inline int
74: sk_leave_group4(sock *s, ip_addr maddr)
75: {
76: struct ip_mreq mr = INIT_MREQ4(maddr, s->iface);
77:
78: if (setsockopt(s->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mr, sizeof(mr)) < 0)
79: ERR("IP_ADD_MEMBERSHIP");
80:
81: return 0;
82: }
83:
84:
85: /*
86: * BSD IPv4 packet control messages
87: */
88:
89: /* It uses IP_RECVDSTADDR / IP_RECVIF socket options instead of IP_PKTINFO */
90:
91: #define CMSG4_SPACE_PKTINFO (CMSG_SPACE(sizeof(struct in_addr)) + \
92: CMSG_SPACE(sizeof(struct sockaddr_dl)))
93: #define CMSG4_SPACE_TTL CMSG_SPACE(sizeof(char))
94:
95: static inline int
96: sk_request_cmsg4_pktinfo(sock *s)
97: {
98: int y = 1;
99:
100: if (setsockopt(s->fd, IPPROTO_IP, IP_RECVDSTADDR, &y, sizeof(y)) < 0)
101: ERR("IP_RECVDSTADDR");
102:
103: if (setsockopt(s->fd, IPPROTO_IP, IP_RECVIF, &y, sizeof(y)) < 0)
104: ERR("IP_RECVIF");
105:
106: return 0;
107: }
108:
109: static inline int
110: sk_request_cmsg4_ttl(sock *s)
111: {
112: int y = 1;
113:
114: if (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &y, sizeof(y)) < 0)
115: ERR("IP_RECVTTL");
116:
117: return 0;
118: }
119:
120: static inline void
121: sk_process_cmsg4_pktinfo(sock *s, struct cmsghdr *cm)
122: {
123: if (cm->cmsg_type == IP_RECVDSTADDR)
124: s->laddr = ipa_from_in4(* (struct in_addr *) CMSG_DATA(cm));
125:
126: if (cm->cmsg_type == IP_RECVIF)
127: s->lifindex = ((struct sockaddr_dl *) CMSG_DATA(cm))->sdl_index;
128: }
129:
130: static inline void
131: sk_process_cmsg4_ttl(sock *s, struct cmsghdr *cm)
132: {
133: if (cm->cmsg_type == IP_RECVTTL)
134: s->rcv_ttl = * (byte *) CMSG_DATA(cm);
135: }
136:
137: #ifdef IP_SENDSRCADDR
138: static inline void
139: sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
140: {
141: /* Unfortunately, IP_SENDSRCADDR does not work for raw IP sockets on BSD kernels */
142:
143: struct cmsghdr *cm;
144: struct in_addr *sa;
145: int controllen = 0;
146:
147: msg->msg_control = cbuf;
148: msg->msg_controllen = cbuflen;
149:
150: cm = CMSG_FIRSTHDR(msg);
151: cm->cmsg_level = IPPROTO_IP;
152: cm->cmsg_type = IP_SENDSRCADDR;
153: cm->cmsg_len = CMSG_LEN(sizeof(*sa));
154: controllen += CMSG_SPACE(sizeof(*sa));
155:
156: sa = (struct in_addr *) CMSG_DATA(cm);
157: *sa = ipa_to_in4(s->saddr);
158:
159: msg->msg_controllen = controllen;
160: }
161: #else
162: static inline void
163: sk_prepare_cmsgs4(sock *s UNUSED, struct msghdr *msg UNUSED, void *cbuf UNUSED, size_t cbuflen UNUSED) { }
164: #endif
165:
166: static void UNUSED
167: sk_prepare_ip_header(sock *s, void *hdr, int dlen)
168: {
169: struct ip *ip = hdr;
170:
171: bzero(ip, 20);
172:
173: ip->ip_v = 4;
174: ip->ip_hl = 5;
175: ip->ip_tos = (s->tos < 0) ? 0 : s->tos;
176: ip->ip_len = 20 + dlen;
177: ip->ip_ttl = (s->ttl < 0) ? 64 : s->ttl;
178: ip->ip_p = s->dport;
179: ip->ip_src = ipa_to_in4(s->saddr);
180: ip->ip_dst = ipa_to_in4(s->daddr);
181:
182: #ifdef __OpenBSD__
183: /* OpenBSD expects ip_len in network order, other BSDs expect host order */
184: ip->ip_len = htons(ip->ip_len);
185: #endif
186: }
187:
188:
189: /*
190: * Miscellaneous BSD socket syscalls
191: */
192:
193: #ifndef TCP_KEYLEN_MAX
194: #define TCP_KEYLEN_MAX 80
195: #endif
196:
197: #ifndef TCP_SIG_SPI
198: #define TCP_SIG_SPI 0x1000
199: #endif
200:
201: #if defined(__FreeBSD__)
202: #define USE_MD5SIG_SETKEY
203: #include "lib/setkey.h"
204: #endif
205:
206: int
207: sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote UNUSED, struct iface *ifa UNUSED, char *passwd, int setkey UNUSED)
208: {
209: #ifdef USE_MD5SIG_SETKEY
210: if (setkey)
211: if (sk_set_md5_in_sasp_db(s, local, remote, ifa, passwd) < 0)
212: return -1;
213: #endif
214:
215: int enable = (passwd && *passwd) ? TCP_SIG_SPI : 0;
216: if (setsockopt(s->fd, IPPROTO_TCP, TCP_MD5SIG, &enable, sizeof(enable)) < 0)
217: {
218: if (errno == ENOPROTOOPT)
219: ERR_MSG("Kernel does not support TCP MD5 signatures");
220: else
221: ERR("TCP_MD5SIG");
222: }
223:
224: return 0;
225: }
226:
227: static inline int
228: sk_set_min_ttl4(sock *s, int ttl)
229: {
230: if (setsockopt(s->fd, IPPROTO_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0)
231: {
232: if (errno == ENOPROTOOPT)
233: ERR_MSG("Kernel does not support IPv4 TTL security");
234: else
235: ERR("IP_MINTTL");
236: }
237:
238: return 0;
239: }
240:
241: static inline int
242: sk_set_min_ttl6(sock *s, int ttl UNUSED)
243: {
244: ERR_MSG("Kernel does not support IPv6 TTL security");
245: }
246:
247: static inline int
248: sk_disable_mtu_disc4(sock *s UNUSED)
249: {
250: /* TODO: Set IP_DONTFRAG to 0 ? */
251: return 0;
252: }
253:
254: static inline int
255: sk_disable_mtu_disc6(sock *s UNUSED)
256: {
257: /* TODO: Set IPV6_DONTFRAG to 0 ? */
258: return 0;
259: }
260:
261: int sk_priority_control = -1;
262:
263: static inline int
264: sk_set_priority(sock *s, int prio UNUSED)
265: {
266: ERR_MSG("Socket priority not supported");
267: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>