Annotation of embedaddon/bird/sysdep/linux/sysio.h, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     BIRD Internet Routing Daemon -- Linux Multicasting and Network Includes
                      3:  *
                      4:  *     (c) 1998--2000 Martin Mares <mj@ucw.cz>
                      5:  *
                      6:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      7:  */
                      8: 
                      9: 
                     10: #ifndef HAVE_STRUCT_IP_MREQN
                     11: /* Several versions of glibc don't define this structure, so we have to do it ourselves */
                     12: struct ip_mreqn
                     13: {
                     14:   struct in_addr imr_multiaddr;                        /* IP multicast address of group */
                     15:   struct in_addr imr_address;                  /* local IP address of interface */
                     16:   int           imr_ifindex;                   /* Interface index */
                     17: };
                     18: #endif
                     19: 
                     20: #ifndef IP_MINTTL
                     21: #define IP_MINTTL 21
                     22: #endif
                     23: 
                     24: #ifndef IPV6_TCLASS
                     25: #define IPV6_TCLASS 67
                     26: #endif
                     27: 
                     28: #ifndef IPV6_MINHOPCOUNT
                     29: #define IPV6_MINHOPCOUNT 73
                     30: #endif
                     31: 
                     32: 
                     33: #ifndef TCP_MD5SIG
                     34: 
                     35: #define TCP_MD5SIG  14
                     36: #define TCP_MD5SIG_MAXKEYLEN 80
                     37: 
                     38: struct tcp_md5sig {
                     39:   struct  sockaddr_storage tcpm_addr;             /* address associated */
                     40:   u16   __tcpm_pad1;                              /* zero */
                     41:   u16   tcpm_keylen;                              /* key length */
                     42:   u32   __tcpm_pad2;                              /* zero */
                     43:   u8    tcpm_key[TCP_MD5SIG_MAXKEYLEN];           /* key (binary) */
                     44: };
                     45: 
                     46: #endif
                     47: 
                     48: 
                     49: /* Linux does not care if sa_len is larger than needed */
                     50: #define SA_LEN(x) sizeof(sockaddr)
                     51: 
                     52: 
                     53: /*
                     54:  *     Linux IPv4 multicast syscalls
                     55:  */
                     56: 
                     57: #define INIT_MREQ4(maddr,ifa) \
                     58:   { .imr_multiaddr = ipa_to_in4(maddr), .imr_ifindex = ifa->index }
                     59: 
                     60: static inline int
                     61: sk_setup_multicast4(sock *s)
                     62: {
                     63:   struct ip_mreqn mr = { .imr_ifindex = s->iface->index };
                     64:   int ttl = s->ttl;
                     65:   int n = 0;
                     66: 
                     67:   /* This defines where should we send _outgoing_ multicasts */
                     68:   if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &mr, sizeof(mr)) < 0)
                     69:     ERR("IP_MULTICAST_IF");
                     70: 
                     71:   if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
                     72:     ERR("IP_MULTICAST_TTL");
                     73: 
                     74:   if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_LOOP, &n, sizeof(n)) < 0)
                     75:     ERR("IP_MULTICAST_LOOP");
                     76: 
                     77:   return 0;
                     78: }
                     79: 
                     80: static inline int
                     81: sk_join_group4(sock *s, ip_addr maddr)
                     82: {
                     83:   struct ip_mreqn mr = INIT_MREQ4(maddr, s->iface);
                     84: 
                     85:   if (setsockopt(s->fd, SOL_IP, IP_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
                     86:     ERR("IP_ADD_MEMBERSHIP");
                     87: 
                     88:   return 0;
                     89: }
                     90: 
                     91: static inline int
                     92: sk_leave_group4(sock *s, ip_addr maddr)
                     93: {
                     94:   struct ip_mreqn mr = INIT_MREQ4(maddr, s->iface);
                     95: 
                     96:   if (setsockopt(s->fd, SOL_IP, IP_DROP_MEMBERSHIP, &mr, sizeof(mr)) < 0)
                     97:     ERR("IP_DROP_MEMBERSHIP");
                     98: 
                     99:   return 0;
                    100: }
                    101: 
                    102: 
                    103: /*
                    104:  *     Linux IPv4 packet control messages
                    105:  */
                    106: 
                    107: /* Mostly similar to standardized IPv6 code */
                    108: 
                    109: #define CMSG4_SPACE_PKTINFO CMSG_SPACE(sizeof(struct in_pktinfo))
                    110: #define CMSG4_SPACE_TTL CMSG_SPACE(sizeof(int))
                    111: 
                    112: static inline int
                    113: sk_request_cmsg4_pktinfo(sock *s)
                    114: {
                    115:   int y = 1;
                    116: 
                    117:   if (setsockopt(s->fd, SOL_IP, IP_PKTINFO, &y, sizeof(y)) < 0)
                    118:     ERR("IP_PKTINFO");
                    119: 
                    120:   return 0;
                    121: }
                    122: 
                    123: static inline int
                    124: sk_request_cmsg4_ttl(sock *s)
                    125: {
                    126:   int y = 1;
                    127: 
                    128:   if (setsockopt(s->fd, SOL_IP, IP_RECVTTL, &y, sizeof(y)) < 0)
                    129:     ERR("IP_RECVTTL");
                    130: 
                    131:   return 0;
                    132: }
                    133: 
                    134: static inline void
                    135: sk_process_cmsg4_pktinfo(sock *s, struct cmsghdr *cm)
                    136: {
                    137:   if (cm->cmsg_type == IP_PKTINFO)
                    138:   {
                    139:     struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cm);
                    140:     s->laddr = ipa_from_in4(pi->ipi_addr);
                    141:     s->lifindex = pi->ipi_ifindex;
                    142:   }
                    143: }
                    144: 
                    145: static inline void
                    146: sk_process_cmsg4_ttl(sock *s, struct cmsghdr *cm)
                    147: {
                    148:   if (cm->cmsg_type == IP_TTL)
                    149:     s->rcv_ttl = * (int *) CMSG_DATA(cm);
                    150: }
                    151: 
                    152: static inline void
                    153: sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
                    154: {
                    155:   struct cmsghdr *cm;
                    156:   struct in_pktinfo *pi;
                    157:   int controllen = 0;
                    158: 
                    159:   msg->msg_control = cbuf;
                    160:   msg->msg_controllen = cbuflen;
                    161: 
                    162:   cm = CMSG_FIRSTHDR(msg);
                    163:   cm->cmsg_level = SOL_IP;
                    164:   cm->cmsg_type = IP_PKTINFO;
                    165:   cm->cmsg_len = CMSG_LEN(sizeof(*pi));
                    166:   controllen += CMSG_SPACE(sizeof(*pi));
                    167: 
                    168:   pi = (struct in_pktinfo *) CMSG_DATA(cm);
                    169:   pi->ipi_ifindex = s->iface ? s->iface->index : 0;
                    170:   pi->ipi_spec_dst = ipa_to_in4(s->saddr);
                    171:   pi->ipi_addr = ipa_to_in4(IPA_NONE);
                    172: 
                    173:   msg->msg_controllen = controllen;
                    174: }
                    175: 
                    176: 
                    177: /*
                    178:  *     Miscellaneous Linux socket syscalls
                    179:  */
                    180: 
                    181: int
                    182: sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, struct iface *ifa, char *passwd, int setkey UNUSED)
                    183: {
                    184:   struct tcp_md5sig md5;
                    185: 
                    186:   memset(&md5, 0, sizeof(md5));
                    187:   sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0);
                    188: 
                    189:   if (passwd)
                    190:   {
                    191:     int len = strlen(passwd);
                    192: 
                    193:     if (len > TCP_MD5SIG_MAXKEYLEN)
                    194:       ERR_MSG("The password for TCP MD5 Signature is too long");
                    195: 
                    196:     md5.tcpm_keylen = len;
                    197:     memcpy(&md5.tcpm_key, passwd, len);
                    198:   }
                    199: 
                    200:   if (setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)) < 0)
                    201:   {
                    202:     if (errno == ENOPROTOOPT)
                    203:       ERR_MSG("Kernel does not support TCP MD5 signatures");
                    204:     else
                    205:       ERR("TCP_MD5SIG");
                    206:   }
                    207: 
                    208:   return 0;
                    209: }
                    210: 
                    211: static inline int
                    212: sk_set_min_ttl4(sock *s, int ttl)
                    213: {
                    214:   if (setsockopt(s->fd, SOL_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0)
                    215:   {
                    216:     if (errno == ENOPROTOOPT)
                    217:       ERR_MSG("Kernel does not support IPv4 TTL security");
                    218:     else
                    219:       ERR("IP_MINTTL");
                    220:   }
                    221: 
                    222:   return 0;
                    223: }
                    224: 
                    225: static inline int
                    226: sk_set_min_ttl6(sock *s, int ttl)
                    227: {
                    228:   if (setsockopt(s->fd, SOL_IPV6, IPV6_MINHOPCOUNT, &ttl, sizeof(ttl)) < 0)
                    229:   {
                    230:     if (errno == ENOPROTOOPT)
                    231:       ERR_MSG("Kernel does not support IPv6 TTL security");
                    232:     else
                    233:       ERR("IPV6_MINHOPCOUNT");
                    234:   }
                    235: 
                    236:   return 0;
                    237: }
                    238: 
                    239: static inline int
                    240: sk_disable_mtu_disc4(sock *s)
                    241: {
                    242:   int dont = IP_PMTUDISC_DONT;
                    243: 
                    244:   if (setsockopt(s->fd, SOL_IP, IP_MTU_DISCOVER, &dont, sizeof(dont)) < 0)
                    245:     ERR("IP_MTU_DISCOVER");
                    246: 
                    247:   return 0;
                    248: }
                    249: 
                    250: static inline int
                    251: sk_disable_mtu_disc6(sock *s)
                    252: {
                    253:   int dont = IPV6_PMTUDISC_DONT;
                    254: 
                    255:   if (setsockopt(s->fd, SOL_IPV6, IPV6_MTU_DISCOVER, &dont, sizeof(dont)) < 0)
                    256:     ERR("IPV6_MTU_DISCOVER");
                    257: 
                    258:   return 0;
                    259: }
                    260: 
                    261: int sk_priority_control = 7;
                    262: 
                    263: static inline int
                    264: sk_set_priority(sock *s, int prio)
                    265: {
                    266:   if (setsockopt(s->fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)) < 0)
                    267:     ERR("SO_PRIORITY");
                    268: 
                    269:   return 0;
                    270: }
                    271: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>