UDP catchall

Matus Harvan mharvan at inf.ethz.ch
Fri Oct 26 08:43:35 PDT 2007


Hi,

I was wondering if I could get some feedback about the patch and
whether others think it could be committed.

Matus

On Sun, Sep 09, 2007 at 10:18:37PM +0200, Matus Harvan wrote:
> Hello,
> 
> I am a Google Summer of Code student working on mtund, aka Magic
> Tunnel Daemon aka Super Tunnel Daemon,
> http://wiki.freebsd.org/SuperTunnelDaemon.
> 
> For mtund it would be useful to listen on all unused UDP ports,
> allowing a client behind firewall to use any possible hole it could
> find. To achieve this, the easiest way seems to be to allow a raw
> IP/UDP socket to receive UDP traffic that no regular UDP socket
> wants. In the kernel this means passing the mbuf from udp_input to
> rip_input(). Upon receiving a packet, the user space program would
> inspect the UDP header and create a UDP socket bound to the correct
> local port and connected to the right remote port and address.
> 
> The user space usage would then look as follows:
> 	fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
> 	recvfrom(fd, ...);
> 	/* parse the UDP header for the source and destination addresses */
> 	new_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
> 	bind(new_fd, ...);
> 	connect(new_fd, ...);
> 
> This catchall feature could be enabled/disabled via a sysctl variable,
> net.inet.raw.udp_catchall. Furthermore, a rate limit could be used to
> mitigate possible DoS misuse.
> 
> A simple testing program can be found under
> 
> http://p4web.freebsd.org/@md=d&cd=//depot/projects/soc2007/mharvan-mtund/sys.patches/test_catchall/&c=xpc@//depot/projects/soc2007/mharvan-mtund/sys.patches/test_catchall/ucatchalld.c?ac=22
> 
> and a more complex example is the udp catchall plugin for mtund
> 
> http://p4web.freebsd.org/@md=d&cd=//depot/projects/soc2007/mharvan-mtund/mtund.src/&c=SM3@//depot/projects/soc2007/mharvan-mtund/mtund.src/plugin_udp_catchall.c?ac=22
> 
> Matus
> 
> patch:
> Index: udp_usrreq.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
> retrieving revision 1.216
> diff -d -u -r1.216 udp_usrreq.c
> --- udp_usrreq.c	10 Jul 2007 09:30:46 -0000	1.216
> +++ udp_usrreq.c	6 Sep 2007 21:59:31 -0000
> @@ -125,6 +125,15 @@
>  SYSCTL_ULONG(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
>      &udp_recvspace, 0, "Maximum space for incoming UDP datagrams");
>  
> +static int	udp_catchall = 0;
> +SYSCTL_INT(_net_inet_raw, OID_AUTO, udp_catchall, CTLFLAG_RW | CTLFLAG_SECURE,
> +   &udp_catchall, 0, "Raw IP UDP sockets receive unclaimed UDP datagrams");
> +
> +static int	catchalllim = 5;
> +SYSCTL_INT(_net_inet_udp, OID_AUTO, catchalllim, CTLFLAG_RW | CTLFLAG_SECURE,
> +   &catchalllim, 0,
> +   "Rate limit on received UDP datagrams due to udp_catchall");
> +
>  struct inpcbhead	udb;		/* from udp_var.h */
>  struct inpcbinfo	udbinfo;
>  
> @@ -136,6 +145,11 @@
>  SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW, &udpstat,
>      udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)");
>  
> +static struct rate {
> +  struct timeval	lasttime;
> +  int		curpps;
> +} catchallr;
> +
>  static void	udp_detach(struct socket *so);
>  static int	udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
>  		    struct mbuf *, struct thread *);
> @@ -515,6 +529,35 @@
>  	 */
>  	inp = in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport,
>  	    ip->ip_dst, uh->uh_dport, 1, ifp);
> +
> +	/* catchall socket */
> +	if (inp == NULL && udp_catchall != 0) {
> +#ifdef DIAGNOSTIC
> +		printf("IP UDP catchall active\n");
> +		char dbuf[INET_ADDRSTRLEN], sbuf[INET_ADDRSTRLEN];
> +		strcpy(dbuf, inet_ntoa(ip->ip_dst));
> +		strcpy(sbuf, inet_ntoa(ip->ip_src));
> +		printf("\tip_src: %s, sport: %hu\n\tip_dst: %s, dport: %hu\n",
> +		    sbuf, ntohs(uh->uh_sport), dbuf, ntohs(uh->uh_dport));
> +#endif
> +
> +		/* rate limiting */
> +		if (catchalllim > 0) 
> +			if (ppsratecheck(&catchallr.lasttime,
> +			    &catchallr.curpps, catchalllim)) {
> +				rip_input(m, off);
> +				INP_INFO_RUNLOCK(&udbinfo);
> +				return;
> +			}
> +#ifdef DIAGNOSTIC
> +			else
> +			  printf("ppsratecheck limited "
> +				    "udp_catchall\n");
> +		else
> +			printf("ppsratecheck limited udp_catchall\n");
> +#endif
> +	}
> +
>  	if (inp == NULL) {
>  		if (udp_log_in_vain) {
>  			char buf[4*sizeof "123"];


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-net/attachments/20071026/b80c4ce6/attachment.pgp


More information about the freebsd-net mailing list