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>