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