Date: Thu, 29 May 2003 12:23:06 -0400 From: Scot Loach <sloach@SANDVINE.com> To: "'freebsd-net@freebsd.org'" <freebsd-net@freebsd.org> Subject: Socket option to get dst port Message-ID: <FE045D4D9F7AED4CBFF1B3B813C8533701AE82E6@mail.sandvine.com>
next in thread | raw e-mail | index | archive | help
When a UDP packet is read from a socket, the userland program can get the destination IP address by using the IP_RECVDSTADDR socket option. This returns the destination address as ancillary data in the msg_control member of the msghdr structure passed to recvmsg(). I needed a way to get the destination port for UDP packets that were forwarded to a local UDP port using ipfw, with the "fwd" option. There doesn't seem to be any way to get this information currently. I added a IP_RECVDSTPORT socket option for this purpose. Unfortunately I had to add the control mbuf within udp_input() instead of within ip_savecontrol() since that's the only place I have the UDP header. Patch to 4.7 is below. Please let me know if you see any problems with it. If this is generally useful, it could be committed. Index: in.h =================================================================== RCS file: /usr/cvs/src/sys/netinet/in.h,v retrieving revision 1.48.2.9 diff -U3 -r1.48.2.9 in.h --- in.h 1 Dec 2002 14:03:10 -0000 1.48.2.9 +++ in.h 29 May 2003 15:56:19 -0000 @@ -333,6 +333,8 @@ #define IP_DUMMYNET_FLUSH 62 /* flush dummynet */ #define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */ +#define IP_RECVDSTPORT 80 /* bool; receive IP dst port w/dgram */ + /* * Defaults and limits for options */ Index: in_pcb.h =================================================================== RCS file: /usr/cvs/src/sys/netinet/in_pcb.h,v retrieving revision 1.32.2.6 diff -U3 -r1.32.2.6 in_pcb.h --- in_pcb.h 29 Jul 2002 18:56:37 -0000 1.32.2.6 +++ in_pcb.h 29 May 2003 15:56:13 -0000 @@ -273,8 +273,10 @@ #define IN6P_RTHDRDSTOPTS 0x200000 /* receive dstoptions before rt hdr */ #define IN6P_AUTOFLOWLABEL 0x800000 /* attach flowlabel automatically */ +#define INP_RECVDSTPORT 0x01000000 /* receive UDP dst port */ + #define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDS TADDR|\ - INP_RECVIF|\ + INP_RECVIF| INP_RECVDSTPORT |\ IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\ IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\ IN6P_AUTOFLOWLABEL) Index: ip_output.c =================================================================== RCS file: /usr/cvs/src/sys/netinet/ip_output.c,v retrieving revision 1.99.2.31 diff -U3 -r1.99.2.31 ip_output.c --- ip_output.c 12 Jul 2002 22:14:12 -0000 1.99.2.31 +++ ip_output.c 28 May 2003 19:32:57 -0000 @@ -1181,6 +1181,7 @@ case IP_RECVOPTS: case IP_RECVRETOPTS: case IP_RECVDSTADDR: + case IP_RECVDSTPORT: case IP_RECVIF: case IP_FAITH: error = sooptcopyin(sopt, &optval, sizeof optval, @@ -1213,6 +1214,10 @@ case IP_RECVDSTADDR: OPTSET(INP_RECVDSTADDR); break; + + case IP_RECVDSTPORT: + OPTSET(INP_RECVDSTPORT); + break; case IP_RECVIF: OPTSET(INP_RECVIF); Index: udp_usrreq.c =================================================================== RCS file: /usr/cvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.64.2.16.1000.2 diff -U3 -r1.64.2.16.1000.2 udp_usrreq.c --- udp_usrreq.c 27 Jan 2003 16:38:06 -0000 1.64.2.16.1000.2 +++ udp_usrreq.c 29 May 2003 15:55:24 -0000 @@ -450,7 +450,18 @@ inp->inp_flags = savedflags; } else #endif - ip_savecontrol(inp, &opts, ip, m); + { + ip_savecontrol(inp, &opts, ip, m); + if (inp->inp_flags & INP_RECVDSTPORT) { + struct mbuf **mp = &opts; + while (*mp) { + mp = &(*mp)->m_next; + } + *mp = sbcreatecontrol((caddr_t) &uh->uh_dport, + sizeof(u_int16_t), IP_RECVDSTPORT, + IPPROTO_IP); + } + } } m_adj(m, iphlen + sizeof(struct udphdr)); #ifdef INET6
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FE045D4D9F7AED4CBFF1B3B813C8533701AE82E6>