Re: [PATCH] Add IPV6_RECVDSTPORT socket option
ok to commit? comment? On Fri, 07 Sep 2012 16:13:53 +0900 UMEZAWA Takeshi umez...@iij.ad.jp wrote: Hello, I have added IPV6_RECVDSTPORT socket option, which enables us to get original (= before divert) destination port of a UDP packet. The way to use this option is same as IP_RECVDSTPORT. The values of IPV6_RECVDSTPORT and IN6P_RECVDSTPORT are temporary. UMEZAWA Takeshi (FAMILY Given) umez...@iij.ad.jp Internet Initiative Japan Inc. diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index dc54d77..0090b85 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -421,6 +421,16 @@ Get or set the ESP encapsulation level. Get or set the .Xr ipcomp 4 level. +.It Dv IPV6_RECVDSTPORT Fa int * +Get or set the status of whether the destination port for a UDP datagram +will be provided as ancillary data along with the payload in subsequent +.Xr recvmsg 2 +calls. The information is stored as a single value of type +.Vt u_int16_t +in network byte order. +.Pp +Turning this option on will result in this socket getting cmsg data of +type IPV6_RECVDSTPORT. .El .Pp The diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 9d4f0d9..def52de 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -196,6 +196,7 @@ struct inpcbtable { */ #define IN6P_HIGHPORTINP_HIGHPORT/* user wants high port */ #define IN6P_LOWPORT INP_LOWPORT /* user wants low port */ +#define IN6P_RECVDSTPORT INP_RECVDSTPORT /* receive IP dst addr before rdr */ #define IN6P_PKTINFO 0x01 /* receive IP6 dst and I/F */ #define IN6P_HOPLIMIT0x02 /* receive hoplimit */ #define IN6P_HOPOPTS 0x04 /* receive hop-by-hop options */ @@ -215,7 +216,7 @@ struct inpcbtable { #define IN6P_CONTROLOPTS (IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\ IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\ IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\ - IN6P_MTU) + IN6P_MTU|IN6P_RECVDSTPORT) #endif #define INPLOOKUP_WILDCARD 1 diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 5a8d8e5..44c3472 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -688,6 +688,16 @@ udp_input(struct mbuf *m, ...) if (ip (inp-inp_flags INP_CONTROLOPTS || inp-inp_socket-so_options SO_TIMESTAMP)) ip_savecontrol(inp, opts, ip, m); +#ifdef INET6 + if (ip6 (inp-inp_flags IN6P_RECVDSTPORT)) { + struct mbuf **mp = opts; + + while (*mp) + mp = (*mp)-m_next; + *mp = sbcreatecontrol((caddr_t)uh-uh_dport, sizeof(u_int16_t), + IPV6_RECVDSTPORT, IPPROTO_IPV6); + } +#endif /* INET6 */ if (ip (inp-inp_flags INP_RECVDSTPORT)) { struct mbuf **mp = opts; diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 664bca9..395ef9d 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -451,6 +451,8 @@ struct route_in6 { #define IPV6_DONTFRAG62 /* bool; disable IPv6 fragmentation */ #define IPV6_PIPEX 63 /* bool; using PIPEX */ +#define IPV6_RECVDSTPORT 64 /* bool; receive IP dst port w/dgram */ + #define IPV6_RTABLE 0x1021 /* int; routing table, see SO_RTABLE */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 07aedee..d4a371d 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1356,6 +1356,7 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname, case IPV6_RECVTCLASS: case IPV6_V6ONLY: case IPV6_AUTOFLOWLABEL: + case IPV6_RECVDSTPORT: if (m == NULL || m-m_len != sizeof(int)) { error = EINVAL; break; @@ -1504,6 +1505,9 @@ do { \ OPTSET(IN6P_AUTOFLOWLABEL); break; + case IPV6_RECVDSTPORT: + OPTSET(IN6P_RECVDSTPORT); + break; } break; @@ -1766,6 +1770,7 @@ do { \ case IPV6_PORTRANGE: case IPV6_RECVTCLASS: case IPV6_AUTOFLOWLABEL: + case IPV6_RECVDSTPORT: switch (optname) { case IPV6_RECVHOPOPTS: @@ -1827,6 +1832,10 @@ do { \
Re: [PATCH] Add IPV6_RECVDSTPORT socket option
On Mon, Sep 17, 2012 at 02:52:42PM +0200, YASUOKA Masahiko wrote: ok to commit? OK bluhm@ comment? On Fri, 07 Sep 2012 16:13:53 +0900 UMEZAWA Takeshi umez...@iij.ad.jp wrote: Hello, I have added IPV6_RECVDSTPORT socket option, which enables us to get original (= before divert) destination port of a UDP packet. The way to use this option is same as IP_RECVDSTPORT. The values of IPV6_RECVDSTPORT and IN6P_RECVDSTPORT are temporary. UMEZAWA Takeshi (FAMILY Given) umez...@iij.ad.jp Internet Initiative Japan Inc. diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index dc54d77..0090b85 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -421,6 +421,16 @@ Get or set the ESP encapsulation level. Get or set the .Xr ipcomp 4 level. +.It Dv IPV6_RECVDSTPORT Fa int * +Get or set the status of whether the destination port for a UDP datagram +will be provided as ancillary data along with the payload in subsequent +.Xr recvmsg 2 +calls. The information is stored as a single value of type +.Vt u_int16_t +in network byte order. +.Pp +Turning this option on will result in this socket getting cmsg data of +type IPV6_RECVDSTPORT. .El .Pp The diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 9d4f0d9..def52de 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -196,6 +196,7 @@ struct inpcbtable { */ #define IN6P_HIGHPORT INP_HIGHPORT/* user wants high port */ #define IN6P_LOWPORT INP_LOWPORT /* user wants low port */ +#define IN6P_RECVDSTPORT INP_RECVDSTPORT /* receive IP dst addr before rdr */ #define IN6P_PKTINFO 0x01 /* receive IP6 dst and I/F */ #define IN6P_HOPLIMIT 0x02 /* receive hoplimit */ #define IN6P_HOPOPTS 0x04 /* receive hop-by-hop options */ @@ -215,7 +216,7 @@ struct inpcbtable { #define IN6P_CONTROLOPTS (IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\ IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\ IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\ -IN6P_MTU) +IN6P_MTU|IN6P_RECVDSTPORT) #endif #defineINPLOOKUP_WILDCARD 1 diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 5a8d8e5..44c3472 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -688,6 +688,16 @@ udp_input(struct mbuf *m, ...) if (ip (inp-inp_flags INP_CONTROLOPTS || inp-inp_socket-so_options SO_TIMESTAMP)) ip_savecontrol(inp, opts, ip, m); +#ifdef INET6 + if (ip6 (inp-inp_flags IN6P_RECVDSTPORT)) { + struct mbuf **mp = opts; + + while (*mp) + mp = (*mp)-m_next; + *mp = sbcreatecontrol((caddr_t)uh-uh_dport, sizeof(u_int16_t), + IPV6_RECVDSTPORT, IPPROTO_IPV6); + } +#endif /* INET6 */ if (ip (inp-inp_flags INP_RECVDSTPORT)) { struct mbuf **mp = opts; diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 664bca9..395ef9d 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -451,6 +451,8 @@ struct route_in6 { #define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */ #define IPV6_PIPEX 63 /* bool; using PIPEX */ +#define IPV6_RECVDSTPORT 64 /* bool; receive IP dst port w/dgram */ + #define IPV6_RTABLE0x1021 /* int; routing table, see SO_RTABLE */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 07aedee..d4a371d 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1356,6 +1356,7 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname, case IPV6_RECVTCLASS: case IPV6_V6ONLY: case IPV6_AUTOFLOWLABEL: + case IPV6_RECVDSTPORT: if (m == NULL || m-m_len != sizeof(int)) { error = EINVAL; break; @@ -1504,6 +1505,9 @@ do { \ OPTSET(IN6P_AUTOFLOWLABEL); break; + case IPV6_RECVDSTPORT: + OPTSET(IN6P_RECVDSTPORT); + break; } break; @@ -1766,6 +1770,7 @@ do { \ case IPV6_PORTRANGE: case IPV6_RECVTCLASS: case IPV6_AUTOFLOWLABEL: + case
[PATCH] Add IPV6_RECVDSTPORT socket option
Hello, I have added IPV6_RECVDSTPORT socket option, which enables us to get original (= before divert) destination port of a UDP packet. The way to use this option is same as IP_RECVDSTPORT. The values of IPV6_RECVDSTPORT and IN6P_RECVDSTPORT are temporary. UMEZAWA Takeshi (FAMILY Given) umez...@iij.ad.jp Internet Initiative Japan Inc. diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index dc54d77..0090b85 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -421,6 +421,16 @@ Get or set the ESP encapsulation level. Get or set the .Xr ipcomp 4 level. +.It Dv IPV6_RECVDSTPORT Fa int * +Get or set the status of whether the destination port for a UDP datagram +will be provided as ancillary data along with the payload in subsequent +.Xr recvmsg 2 +calls. The information is stored as a single value of type +.Vt u_int16_t +in network byte order. +.Pp +Turning this option on will result in this socket getting cmsg data of +type IPV6_RECVDSTPORT. .El .Pp The diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 9d4f0d9..def52de 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -196,6 +196,7 @@ struct inpcbtable { */ #define IN6P_HIGHPORT INP_HIGHPORT/* user wants high port */ #define IN6P_LOWPORT INP_LOWPORT /* user wants low port */ +#define IN6P_RECVDSTPORT INP_RECVDSTPORT /* receive IP dst addr before rdr */ #define IN6P_PKTINFO 0x01 /* receive IP6 dst and I/F */ #define IN6P_HOPLIMIT 0x02 /* receive hoplimit */ #define IN6P_HOPOPTS 0x04 /* receive hop-by-hop options */ @@ -215,7 +216,7 @@ struct inpcbtable { #define IN6P_CONTROLOPTS (IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\ IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\ IN6P_TCLASS|IN6P_AUTOFLOWLABEL|IN6P_RFC2292|\ -IN6P_MTU) +IN6P_MTU|IN6P_RECVDSTPORT) #endif #defineINPLOOKUP_WILDCARD 1 diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 5a8d8e5..44c3472 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -688,6 +688,16 @@ udp_input(struct mbuf *m, ...) if (ip (inp-inp_flags INP_CONTROLOPTS || inp-inp_socket-so_options SO_TIMESTAMP)) ip_savecontrol(inp, opts, ip, m); +#ifdef INET6 + if (ip6 (inp-inp_flags IN6P_RECVDSTPORT)) { + struct mbuf **mp = opts; + + while (*mp) + mp = (*mp)-m_next; + *mp = sbcreatecontrol((caddr_t)uh-uh_dport, sizeof(u_int16_t), + IPV6_RECVDSTPORT, IPPROTO_IPV6); + } +#endif /* INET6 */ if (ip (inp-inp_flags INP_RECVDSTPORT)) { struct mbuf **mp = opts; diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 664bca9..395ef9d 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -451,6 +451,8 @@ struct route_in6 { #define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */ #define IPV6_PIPEX 63 /* bool; using PIPEX */ +#define IPV6_RECVDSTPORT 64 /* bool; receive IP dst port w/dgram */ + #define IPV6_RTABLE0x1021 /* int; routing table, see SO_RTABLE */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 07aedee..d4a371d 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1356,6 +1356,7 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname, case IPV6_RECVTCLASS: case IPV6_V6ONLY: case IPV6_AUTOFLOWLABEL: + case IPV6_RECVDSTPORT: if (m == NULL || m-m_len != sizeof(int)) { error = EINVAL; break; @@ -1504,6 +1505,9 @@ do { \ OPTSET(IN6P_AUTOFLOWLABEL); break; + case IPV6_RECVDSTPORT: + OPTSET(IN6P_RECVDSTPORT); + break; } break; @@ -1766,6 +1770,7 @@ do { \ case IPV6_PORTRANGE: case IPV6_RECVTCLASS: case IPV6_AUTOFLOWLABEL: + case IPV6_RECVDSTPORT: switch (optname) { case IPV6_RECVHOPOPTS: @@ -1827,6 +1832,10 @@ do { \ case IPV6_AUTOFLOWLABEL: optval = OPTBIT(IN6P_AUTOFLOWLABEL);