diff options
Diffstat (limited to 'sysdep/bsd')
-rw-r--r-- | sysdep/bsd/sysio.h | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h index 085f16fa..031eac9a 100644 --- a/sysdep/bsd/sysio.h +++ b/sysdep/bsd/sysio.h @@ -113,7 +113,9 @@ sysio_leave_group(sock *s, ip_addr maddr) /* BSD RX/TX packet info handling for IPv4 */ /* it uses IP_RECVDSTADDR / IP_RECVIF socket options instead of IP_PKTINFO */ -#define CMSG_RX_SPACE (CMSG_SPACE(sizeof(struct in_addr)) + CMSG_SPACE(sizeof(struct sockaddr_dl))) +#define CMSG_RX_SPACE (CMSG_SPACE(sizeof(struct in_addr)) + \ + CMSG_SPACE(sizeof(struct sockaddr_dl)) + \ + CMSG_SPACE(sizeof(char))) #define CMSG_TX_SPACE CMSG_SPACE(sizeof(struct in_addr)) static char * @@ -121,13 +123,18 @@ sysio_register_cmsgs(sock *s) { int ok = 1; if (s->flags & SKF_LADDR_RX) - { - if (setsockopt(s->fd, IPPROTO_IP, IP_RECVDSTADDR, &ok, sizeof(ok)) < 0) - return "IP_RECVDSTADDR"; + { + if (setsockopt(s->fd, IPPROTO_IP, IP_RECVDSTADDR, &ok, sizeof(ok)) < 0) + return "IP_RECVDSTADDR"; + + if (setsockopt(s->fd, IPPROTO_IP, IP_RECVIF, &ok, sizeof(ok)) < 0) + return "IP_RECVIF"; + } + + if ((s->flags & SKF_TTL_RX) && + (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0)) + return "IP_RECVTTL"; - if (setsockopt(s->fd, IPPROTO_IP, IP_RECVIF, &ok, sizeof(ok)) < 0) - return "IP_RECVIF"; - } return NULL; } @@ -136,27 +143,35 @@ static void sysio_process_rx_cmsgs(sock *s, struct msghdr *msg) { struct cmsghdr *cm; + struct in_addr *ra = NULL; + struct sockaddr_dl *ri = NULL; + unsigned char *ttl = NULL; - if (!(s->flags & SKF_LADDR_RX)) - return; + for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) + { + if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR) + ra = (struct in_addr *) CMSG_DATA(cm); - s->laddr = IPA_NONE; - s->lifindex = 0; + if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF) + ri = (struct sockaddr_dl *) CMSG_DATA(cm); - for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) - { - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR) - { - struct in_addr *ra = (struct in_addr *) CMSG_DATA(cm); - get_inaddr(&s->laddr, ra); - } + if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVTTL) + ttl = (unsigned char *) CMSG_DATA(cm); + } - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF) - { - struct sockaddr_dl *ri = (struct sockaddr_dl *) CMSG_DATA(cm); - s->lifindex = ri->sdl_index; - } - } + if (s->flags & SKF_LADDR_RX) + { + s->laddr = IPA_NONE; + s->lifindex = 0; + + if (ra) + get_inaddr(&s->laddr, ra); + if (ri) + s->lifindex = ri->sdl_index; + } + + if (s->flags & SKF_TTL_RX) + s->ttl = ttl ? *ttl : -1; // log(L_WARN "RX %I %d", s->laddr, s->lifindex); } |