summaryrefslogtreecommitdiff
path: root/sysdep/bsd/sysio.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep/bsd/sysio.h')
-rw-r--r--sysdep/bsd/sysio.h63
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);
}