Module Name: src Committed By: christos Date: Thu Jun 27 19:38:16 UTC 2013
Modified Files: src/sys/netinet: in.h in_pcb.h ip_input.c ip_output.c Log Message: implement IP_PKTINFO and IP_RECVPKTINFO. To generate a diff of this commit: cvs rdiff -u -r1.88 -r1.89 src/sys/netinet/in.h cvs rdiff -u -r1.50 -r1.51 src/sys/netinet/in_pcb.h cvs rdiff -u -r1.305 -r1.306 src/sys/netinet/ip_input.c cvs rdiff -u -r1.222 -r1.223 src/sys/netinet/ip_output.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/in.h diff -u src/sys/netinet/in.h:1.88 src/sys/netinet/in.h:1.89 --- src/sys/netinet/in.h:1.88 Sat Apr 27 17:35:24 2013 +++ src/sys/netinet/in.h Thu Jun 27 15:38:16 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: in.h,v 1.88 2013/04/27 21:35:24 joerg Exp $ */ +/* $NetBSD: in.h,v 1.89 2013/06/27 19:38:16 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1990, 1993 @@ -287,6 +287,17 @@ struct ip_opts { #endif #define IP_RECVTTL 23 /* bool; receive IP TTL w/dgram */ #define IP_MINTTL 24 /* minimum TTL for packet or drop */ +#define IP_PKTINFO 25 /* int; send interface and src addr */ +#define IP_RECVPKTINFO 26 /* int; send interface and dst addr */ + +/* + * Information sent in the control message of a datagram socket for + * IP_PKTINFO and IP_RECVPKTINFO. + */ +struct in_pktinfo { + struct in_addr ipi_addr; /* src/dst address */ + unsigned int ipi_ifindex; /* interface index */ +}; /* * Defaults and limits for options Index: src/sys/netinet/in_pcb.h diff -u src/sys/netinet/in_pcb.h:1.50 src/sys/netinet/in_pcb.h:1.51 --- src/sys/netinet/in_pcb.h:1.50 Mon Jun 25 11:28:39 2012 +++ src/sys/netinet/in_pcb.h Thu Jun 27 15:38:16 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: in_pcb.h,v 1.50 2012/06/25 15:28:39 christos Exp $ */ +/* $NetBSD: in_pcb.h,v 1.51 2013/06/27 19:38:16 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -100,28 +100,31 @@ struct inpcb { #define inp_laddr inp_ip.ip_src /* flags in inp_flags: */ -#define INP_RECVOPTS 0x01 /* receive incoming IP options */ -#define INP_RECVRETOPTS 0x02 /* receive IP options for reply */ -#define INP_RECVDSTADDR 0x04 /* receive IP dst address */ -#define INP_HDRINCL 0x08 /* user supplies entire IP header */ -#define INP_HIGHPORT 0x10 /* (unused; FreeBSD compat) */ -#define INP_LOWPORT 0x20 /* user wants "low" port binding */ -#define INP_ANONPORT 0x40 /* port chosen for user */ -#define INP_RECVIF 0x80 /* receive incoming interface */ +#define INP_RECVOPTS 0x0001 /* receive incoming IP options */ +#define INP_RECVRETOPTS 0x0002 /* receive IP options for reply */ +#define INP_RECVDSTADDR 0x0004 /* receive IP dst address */ +#define INP_HDRINCL 0x0008 /* user supplies entire IP header */ +#define INP_HIGHPORT 0x0010 /* (unused; FreeBSD compat) */ +#define INP_LOWPORT 0x0020 /* user wants "low" port binding */ +#define INP_ANONPORT 0x0040 /* port chosen for user */ +#define INP_RECVIF 0x0080 /* receive incoming interface */ /* XXX should move to an UDP control block */ -#define INP_ESPINUDP 0x100 /* ESP over UDP for NAT-T */ -#define INP_ESPINUDP_NON_IKE 0x200 /* ESP over UDP for NAT-T */ +#define INP_ESPINUDP 0x0100 /* ESP over UDP for NAT-T */ +#define INP_ESPINUDP_NON_IKE 0x0200 /* ESP over UDP for NAT-T */ #define INP_ESPINUDP_ALL (INP_ESPINUDP|INP_ESPINUDP_NON_IKE) -#define INP_NOHEADER 0x400 /* Kernel removes IP header +#define INP_NOHEADER 0x0400 /* Kernel removes IP header * before feeding a packet * to the raw socket user. * The socket user will * not supply an IP header. * Cancels INP_HDRINCL. */ -#define INP_RECVTTL 0x800 /* receive incoming IP TTL */ +#define INP_RECVTTL 0x0800 /* receive incoming IP TTL */ +#define INP_PKTINFO 0x1000 /* receive dst packet info */ +#define INP_RECVPKTINFO 0x2000 /* receive dst packet info */ #define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\ - INP_RECVIF|INP_RECVTTL) + INP_RECVIF|INP_RECVTTL|INP_RECVPKTINFO|\ + INP_PKTINFO) #define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb) Index: src/sys/netinet/ip_input.c diff -u src/sys/netinet/ip_input.c:1.305 src/sys/netinet/ip_input.c:1.306 --- src/sys/netinet/ip_input.c:1.305 Sat Jun 8 09:50:22 2013 +++ src/sys/netinet/ip_input.c Thu Jun 27 15:38:16 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.305 2013/06/08 13:50:22 rmind Exp $ */ +/* $NetBSD: ip_input.c,v 1.306 2013/06/27 19:38:16 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.305 2013/06/08 13:50:22 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.306 2013/06/27 19:38:16 christos Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -1405,6 +1405,24 @@ ip_savecontrol(struct inpcb *inp, struct if (*mp) mp = &(*mp)->m_next; } + if (inp->inp_flags & INP_RECVPKTINFO) { + struct in_pktinfo ipi; + ipi.ipi_addr = ip->ip_dst; + ipi.ipi_ifindex = m->m_pkthdr.rcvif->if_index; + *mp = sbcreatecontrol((void *) &ipi, + sizeof(ipi), IP_RECVPKTINFO, IPPROTO_IP); + if (*mp) + mp = &(*mp)->m_next; + } + if (inp->inp_flags & INP_PKTINFO) { + struct in_pktinfo ipi; + ipi.ipi_addr = ip->ip_src; + ipi.ipi_ifindex = m->m_pkthdr.rcvif->if_index; + *mp = sbcreatecontrol((void *) &ipi, + sizeof(ipi), IP_PKTINFO, IPPROTO_IP); + if (*mp) + mp = &(*mp)->m_next; + } #ifdef notyet /* * XXX Index: src/sys/netinet/ip_output.c diff -u src/sys/netinet/ip_output.c:1.222 src/sys/netinet/ip_output.c:1.223 --- src/sys/netinet/ip_output.c:1.222 Sat Jun 8 09:50:22 2013 +++ src/sys/netinet/ip_output.c Thu Jun 27 15:38:16 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_output.c,v 1.222 2013/06/08 13:50:22 rmind Exp $ */ +/* $NetBSD: ip_output.c,v 1.223 2013/06/27 19:38:16 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.222 2013/06/08 13:50:22 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.223 2013/06/27 19:38:16 christos Exp $"); #include "opt_pfil_hooks.h" #include "opt_inet.h" @@ -949,10 +949,12 @@ ip_ctloutput(int op, struct socket *so, case IP_TOS: case IP_TTL: case IP_MINTTL: + case IP_PKTINFO: case IP_RECVOPTS: case IP_RECVRETOPTS: case IP_RECVDSTADDR: case IP_RECVIF: + case IP_RECVPKTINFO: case IP_RECVTTL: error = sockopt_getint(sopt, &optval); if (error) @@ -979,10 +981,18 @@ ip_ctloutput(int op, struct socket *so, else \ inp->inp_flags &= ~bit; + case IP_PKTINFO: + OPTSET(INP_PKTINFO); + break; + case IP_RECVOPTS: OPTSET(INP_RECVOPTS); break; + case IP_RECVPKTINFO: + OPTSET(INP_RECVPKTINFO); + break; + case IP_RECVRETOPTS: OPTSET(INP_RECVRETOPTS); break; @@ -1073,6 +1083,7 @@ ip_ctloutput(int op, struct socket *so, } break; + case IP_PKTINFO: case IP_TOS: case IP_TTL: case IP_MINTTL: @@ -1080,6 +1091,7 @@ ip_ctloutput(int op, struct socket *so, case IP_RECVRETOPTS: case IP_RECVDSTADDR: case IP_RECVIF: + case IP_RECVPKTINFO: case IP_RECVTTL: case IP_ERRORMTU: switch (sopt->sopt_name) { @@ -1101,10 +1113,18 @@ ip_ctloutput(int op, struct socket *so, #define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0) + case IP_PKTINFO: + optval = OPTBIT(INP_PKTINFO); + break; + case IP_RECVOPTS: optval = OPTBIT(INP_RECVOPTS); break; + case IP_RECVPKTINFO: + optval = OPTBIT(INP_RECVPKTINFO); + break; + case IP_RECVRETOPTS: optval = OPTBIT(INP_RECVRETOPTS); break;