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