File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / sysdep / linux / sysio.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 19:50:23 2021 UTC (3 years, 4 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, HEAD
bird 1.6.8

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

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