Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Aug 2007 17:53:09 GMT
From:      Matus Harvan <mharvan@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 125061 for review
Message-ID:  <200708111753.l7BHr9rh075015@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125061

Change 125061 by mharvan@mharvan_bike-planet on 2007/08/11 17:52:45

	sys patch for receiving unclaimed UDP traffic on a raw IP port

Affected files ...

.. //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/catchall.sys.patch#2 edit
.. //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/test_catchall/Makefile#2 edit
.. //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/test_catchall/README#2 edit
.. //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/test_catchall/ucatchalld.c#3 edit
.. //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/usr_include.patch#2 edit

Differences ...

==== //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/catchall.sys.patch#2 (text+ko) ====

@@ -1,26 +1,29 @@
-Index: in_proto.c
+Index: in.h
 ===================================================================
-RCS file: /home/ncvs/src/sys/netinet/in_proto.c,v
-retrieving revision 1.77.2.3
-diff -u -r1.77.2.3 in_proto.c
---- in_proto.c	3 Jan 2006 08:15:32 -0000	1.77.2.3
-+++ in_proto.c	10 Aug 2007 14:22:01 -0000
-@@ -122,7 +122,7 @@
- 	.pr_flags =		PR_ATOMIC|PR_ADDR,
- 	.pr_input =		udp_input,
- 	.pr_ctlinput =		udp_ctlinput,
--	.pr_ctloutput =		ip_ctloutput,
-+	.pr_ctloutput =		udp_ctloutput,
- 	.pr_init =		udp_init,
- 	.pr_usrreqs =		&udp_usrreqs
- },
+RCS file: /home/ncvs/src/sys/netinet/in.h,v
+retrieving revision 1.90.2.5
+diff -u -r1.90.2.5 in.h
+--- in.h	14 Feb 2007 13:39:01 -0000	1.90.2.5
++++ in.h	11 Aug 2007 17:43:22 -0000
+@@ -429,6 +429,11 @@
+ #define	IP_MINTTL		66   /* minimum TTL for packet or drop */
+ #define	IP_DONTFRAG		67   /* don't fragment packet */
+ 
++#define	IP_UDP_CATCHALL		68   /* a raw socket should receive
++				      * UDP traffic unclaimed by other
++				      * UDP sockets
++				      */
++
+ /*
+  * Defaults and limits for options
+  */
 Index: tcp.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/tcp.h,v
 retrieving revision 1.31.2.2
 diff -u -r1.31.2.2 tcp.h
 --- tcp.h	5 Mar 2007 10:21:52 -0000	1.31.2.2
-+++ tcp.h	10 Aug 2007 14:22:01 -0000
++++ tcp.h	11 Aug 2007 17:43:23 -0000
 @@ -160,6 +160,7 @@
  #define TCP_NOOPT	0x08	/* don't use TCP options */
  #define TCP_MD5SIG	0x10	/* use MD5 digests (RFC2385) */
@@ -35,7 +38,7 @@
 retrieving revision 1.281.2.13
 diff -u -r1.281.2.13 tcp_input.c
 --- tcp_input.c	12 Jun 2007 18:53:32 -0000	1.281.2.13
-+++ tcp_input.c	10 Aug 2007 14:22:03 -0000
++++ tcp_input.c	11 Aug 2007 17:43:25 -0000
 @@ -159,10 +159,16 @@
  	   &tcp_reass_overflows, 0,
  	   "Global number of TCP Segment Reassembly Queue Overflows");
@@ -104,7 +107,7 @@
 retrieving revision 1.228.2.14
 diff -u -r1.228.2.14 tcp_subr.c
 --- tcp_subr.c	30 Dec 2006 17:58:46 -0000	1.228.2.14
-+++ tcp_subr.c	10 Aug 2007 14:22:05 -0000
++++ tcp_subr.c	11 Aug 2007 17:43:28 -0000
 @@ -324,6 +324,10 @@
  	tcp_rexmit_slop = TCPTV_CPU_VAR;
  	tcp_inflight_rttthresh = TCPTV_INFLIGHT_RTTTHRESH;
@@ -122,7 +125,7 @@
 retrieving revision 1.124.2.6
 diff -u -r1.124.2.6 tcp_usrreq.c
 --- tcp_usrreq.c	8 Jan 2007 18:10:12 -0000	1.124.2.6
-+++ tcp_usrreq.c	10 Aug 2007 14:22:07 -0000
++++ tcp_usrreq.c	11 Aug 2007 17:43:29 -0000
 @@ -162,6 +162,12 @@
  		INP_INFO_WUNLOCK(&tcbinfo);
  		return error;
@@ -194,7 +197,7 @@
 retrieving revision 1.126.2.3
 diff -u -r1.126.2.3 tcp_var.h
 --- tcp_var.h	19 Sep 2006 12:58:40 -0000	1.126.2.3
-+++ tcp_var.h	10 Aug 2007 14:22:08 -0000
++++ tcp_var.h	11 Aug 2007 17:43:30 -0000
 @@ -504,6 +504,7 @@
  
  extern	struct inpcbhead tcb;		/* head of queue of active tcpcb's */
@@ -203,62 +206,30 @@
  extern	struct tcpstat tcpstat;	/* tcp statistics */
  extern	int tcp_mssdflt;	/* XXX */
  extern	int tcp_minmss;
-Index: udp.h
-===================================================================
-RCS file: /home/ncvs/src/sys/netinet/udp.h,v
-retrieving revision 1.9
-diff -u -r1.9 udp.h
---- udp.h	7 Jan 2005 01:45:45 -0000	1.9
-+++ udp.h	10 Aug 2007 14:22:08 -0000
-@@ -44,4 +44,9 @@
- 	u_short	uh_sum;			/* udp checksum */
- };
- 
-+/*
-+ * User-settable options (used with setsockopt).
-+ */
-+#define	UDP_CATCHALL	0x1	/* bind to all unused UDP ports */
-+
- #endif
 Index: udp_usrreq.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
 retrieving revision 1.175.2.11
 diff -u -r1.175.2.11 udp_usrreq.c
 --- udp_usrreq.c	10 Jun 2007 07:28:29 -0000	1.175.2.11
-+++ udp_usrreq.c	10 Aug 2007 14:22:09 -0000
-@@ -110,6 +110,11 @@
++++ udp_usrreq.c	11 Aug 2007 17:43:30 -0000
+@@ -110,6 +110,15 @@
  SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW,
  	&strict_mcast_mship, 0, "Only send multicast to member sockets");
  
++static int	udp_catchall = 0;
++SYSCTL_INT(_net_inet_raw, OID_AUTO, udp_catchall, CTLFLAG_RW,
++   &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,
-+	&catchalllim, 0,
-+	   "Rate limit on sockets created by the UDP_CATCHALL socket");
++   &catchalllim, 0,
++   "Rate limit on received UDP datagrams due to udp_catchall");
 +
  struct	inpcbhead udb;		/* from udp_var.h */
  #define	udb6	udb  /* for KAME src sync over BSD*'s */
  struct	inpcbinfo udbinfo;
-@@ -122,6 +127,8 @@
- SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW,
-     &udpstat, udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)");
- 
-+struct inpcb *inp_ucatchall;	/* binding to all unused UDPP ports */
-+
- static void udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
- 		int off, struct sockaddr_in *udp_in);
- 
-@@ -159,6 +166,9 @@
- 	uma_zone_set_max(udbinfo.ipi_zone, maxsockets);
- 	EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
- 		EVENTHANDLER_PRI_ANY);
-+	printf("UDP_CATCHALL initialization (was 0x%x)\n", 
-+	       (unsigned int)inp_ucatchall);
-+	inp_ucatchall = NULL;
- }
- 
- void
-@@ -177,6 +187,11 @@
+@@ -177,6 +186,11 @@
  	struct m_tag *fwd_tag;
  #endif
  
@@ -270,15 +241,14 @@
  	udpstat.udps_ipackets++;
  
  	/*
-@@ -397,6 +412,29 @@
+@@ -397,6 +411,30 @@
  	 */
  	inp = in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport,
  	    ip->ip_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif);
 +
 +	/* catchall socket */
-+	if ((inp == NULL) && (inp_ucatchall != NULL)) {
-+		printf("UDP catchall socket used (0x%x)\n",
-+		    (unsigned int)inp_ucatchall);
++	if (inp == NULL && udp_catchall != 0) {
++		printf("IP UDP catchall active\n");
 +		char dbuf[4*sizeof "123"], sbuf[4*sizeof "123"];
 +		strcpy(dbuf, inet_ntoa(ip->ip_dst));
 +		strcpy(sbuf, inet_ntoa(ip->ip_src));
@@ -287,10 +257,12 @@
 +
 +		/* rate limiting */
 +		if (catchalllim > 0) 
-+		    if (ppsratecheck(&catchallr.lasttime,
-+				     &catchallr.curpps, catchalllim))
-+					inp = inp_ucatchall;
-+		    else
++			if (ppsratecheck(&catchallr.lasttime,
++			    &catchallr.curpps, catchalllim)) {
++				rip_input(m, off);
++				INP_INFO_RUNLOCK(&udbinfo);
++				return;
++			} else
 +				printf("ppsratecheck limited "
 +				    "udp_catchall\n");
 +		else
@@ -300,159 +272,3 @@
  	if (inp == NULL) {
  		if (log_in_vain) {
  			char buf[4*sizeof "123"];
-@@ -580,6 +618,94 @@
- 		in_pcbnotifyall(&udbinfo, faddr, inetctlerrmap[cmd], notify);
- }
- 
-+int
-+udp_ctloutput(so, sopt)
-+	struct socket *so;
-+	struct sockopt *sopt;
-+{
-+	int	error, optval;
-+	struct	inpcb *inp;
-+
-+	error = 0;
-+	INP_INFO_RLOCK(&udbinfo);
-+	inp = sotoinpcb(so);
-+	if (inp == NULL) {
-+		INP_INFO_RUNLOCK(&udbinfo);
-+		return (ECONNRESET);
-+	}
-+	INP_LOCK(inp);
-+	INP_INFO_RUNLOCK(&udbinfo);
-+	if (sopt->sopt_level != IPPROTO_UDP) {
-+		INP_UNLOCK(inp);
-+#ifdef INET6
-+		if (INP_CHECK_SOCKAF(so, AF_INET6))
-+			error = ip6_ctloutput(so, sopt);
-+		else
-+#endif /* INET6 */
-+		error = ip_ctloutput_pcbinfo(so, sopt, &udbinfo);
-+		return (error);
-+	}
-+
-+	switch (sopt->sopt_dir) {
-+	case SOPT_SET:
-+		switch (sopt->sopt_name) {
-+		case UDP_CATCHALL:
-+			printf("UDP_CATCHALL option code\n");
-+			error = sooptcopyin(sopt, &optval, sizeof optval,
-+					    sizeof optval);
-+			if (error)
-+				break;
-+
-+			printf("UDP_CATCHALL optval: %d\n", optval);
-+			if (optval > 0) { /* enable CATCHALL */
-+				printf("request to enable UDP_CATCHALL\n");
-+				if (inp_ucatchall == NULL) {
-+					printf("enabled UDP_CATCHALL\n");
-+					inp_ucatchall = inp;
-+				} else {
-+					printf("UDP_CATCHALL already enabled, "
-+					    "ignoring setsockopt()\n");
-+					error = EINVAL;
-+				}
-+			} else {/* disable CATCHALL */
-+				printf("request to disable UDP_CATCHALL\n");
-+				if (inp_ucatchall == inp) {
-+					printf("disabled UDP_CATCHALL\n");
-+					inp_ucatchall = NULL;
-+				} else {
-+					printf("UDP_CATCHALL already disabled"
-+					       ", ignoring setsockopt()\n");
-+					error = EINVAL;
-+				}
-+			}
-+			break;
-+
-+		default:
-+			error = ENOPROTOOPT;
-+			break;
-+		}
-+		break;
-+
-+	case SOPT_GET:
-+		switch (sopt->sopt_name) {
-+		case UDP_CATCHALL:
-+			if (inp == inp_ucatchall)		    
-+				optval = 1;
-+			else
-+				optval = 0;
-+			error = sooptcopyout(sopt, &optval, sizeof optval);
-+			break;
-+		default:
-+			error = ENOPROTOOPT;
-+			break;
-+		}
-+		break;
-+	}
-+	INP_UNLOCK(inp);
-+	return (error);
-+}
-+
-+
- static int
- udp_pcblist(SYSCTL_HANDLER_ARGS)
- {
-@@ -1070,6 +1196,12 @@
- 	INP_LOCK(inp);
- 	in_pcbdetach(inp);
- 	INP_INFO_WUNLOCK(&udbinfo);
-+
-+	if (inp == inp_ucatchall) {
-+		printf("deactivating UDP_CATCHALL - udp_detach()\n");
-+		inp_ucatchall = NULL;
-+	}
-+
- 	return 0;
- }
- 
-@@ -1096,6 +1228,12 @@
- 	INP_UNLOCK(inp);
- 	INP_INFO_WUNLOCK(&udbinfo);
- 	so->so_state &= ~SS_ISCONNECTED;		/* XXX */
-+
-+	if (inp == inp_ucatchall) {
-+		printf("deactivating UDP_CATCHALL - udp_disconnect()\n");
-+		inp_ucatchall = NULL;
-+	}
-+
- 	return 0;
- }
- 
-@@ -1124,6 +1262,12 @@
- 	INP_INFO_RUNLOCK(&udbinfo);
- 	socantsendmore(so);
- 	INP_UNLOCK(inp);
-+
-+	if (inp == inp_ucatchall) {
-+		printf("deactivating UDP_CATCHALL - udp_shutdown()\n");
-+		inp_ucatchall = NULL;
-+	}
-+
- 	return 0;
- }
- 
-Index: udp_var.h
-===================================================================
-RCS file: /home/ncvs/src/sys/netinet/udp_var.h,v
-retrieving revision 1.29
-diff -u -r1.29 udp_var.h
---- udp_var.h	7 Jan 2005 01:45:45 -0000	1.29
-+++ udp_var.h	10 Aug 2007 14:22:09 -0000
-@@ -94,12 +94,14 @@
- extern struct	pr_usrreqs udp_usrreqs;
- extern struct	inpcbhead udb;
- extern struct	inpcbinfo udbinfo;
-+extern  struct inpcb *inp_ucatchall;	/* binding to all unused UDP ports */
- extern u_long	udp_sendspace;
- extern u_long	udp_recvspace;
- extern struct	udpstat udpstat;
- extern int	log_in_vain;
- 
- void	udp_ctlinput(int, struct sockaddr *, void *);
-+int	udp_ctloutput(struct socket *, struct sockopt *);
- void	udp_init(void);
- void	udp_input(struct mbuf *, int);
- 

==== //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/test_catchall/Makefile#2 (text+ko) ====


==== //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/test_catchall/README#2 (text+ko) ====

@@ -1,7 +1,16 @@
 Testing TCP_CATCHALL and the rate limit:
 	for i in `jot 10`; do nc snowwhite 1236 & done
 
+Assuming the TCP catchall daemon is listening on port 1234 on host snowwhite
+and no socket is bound to TCP port 1236.
+
+-------------------------------------------------------------------------------
 Testing UDP_CATCHALL:
-	nc -u snowwhite 1236
+	for i in `jot 5`; do echo 1234 | nc -u snowwhite 1234 & done
+
+Assuming the UDP catchall daemon is listening on host snowwhite
+and no socket is bound to UDP port 1236.
 
-Assuming the catchall daemon is listening on port 1234 on host snowwhite...
+Note that ucatchalld has to be run as root (to be able to create a raw
+IP socket) and the net.inet.raw.udp_catchall sysctl variable has to be
+set to 1 (or any non-zero value).

==== //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/test_catchall/ucatchalld.c#3 (text+ko) ====

@@ -15,287 +15,57 @@
 #include <netinet/udp.h>
 
 #define SOCKET_TIMEOUT 10
+#define BUFLEN 1500
 
-static int
-udp_connect(char *host, char *port)
-{
-    struct addrinfo hints, *ai_list, *ai;
-    int n, fd = 0;
 
-    memset(&hints, 0, sizeof(hints));
-    //hints.ai_family = AF_UNSPEC;
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_DGRAM;
-
-    n = getaddrinfo(host, port, &hints, &ai_list);
-    if (n) {
-        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(n));
-        exit(EXIT_FAILURE);
-    }
-
-    for (ai = ai_list; ai; ai = ai->ai_next) {
-        fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-        if (fd < 0) {
-            continue;
-        }
-        if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
-            break;
-        }
-        close(fd);
-    }
-
-    freeaddrinfo(ai_list);
-
-    if (ai == NULL) {
-        fprintf(stderr, "socket or connect: failed for %s port %s\n",
-		host, port);
-//        exit(EXIT_FAILURE);
-                return -1;
-    }
-
-    return fd;
-}
-
-/*
- * Create a named UDP endpoint. First get the list of potential
- * network layer addresses and transport layer port numbers. Iterate
- * through the returned address list until an attempt to create a UDP
- * endpoint is successful (or no other alternative exists).
- */
-
-static int
-udp_open(char *port)
+static void
+dump(char *data, int len)
 {
-    struct addrinfo hints, *ai_list, *ai;
-    int n, fd = 0, on = 1;
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_flags = AI_PASSIVE;
-    //hints.ai_family = AF_UNSPEC;
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_DGRAM;
-
-    n = getaddrinfo(NULL, port, &hints, &ai_list);
-    if (n) {
-        fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(n));
-        return -1;
-    }
-
-    for (ai = ai_list; ai; ai = ai->ai_next) {
-        fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-        if (fd < 0) {
-            continue;
-        }
-
-        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-        if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
-            break;
-        }
-        close(fd);
-    }
-
-    freeaddrinfo(ai_list);
-
-    if (ai == NULL) {
-        fprintf(stderr, "bind failed for port %s\n", port);
-        return -1;
-    }
-
-    return fd;
-}
-
-/*
- * Close a udp socket. This function trivially calls close() on
- * POSIX systems, but might be more complicated on other systems.
- */
-
-static int
-udp_close(int fd)
-{
-    return close(fd);
-}
-
-/*
- * Create a listening TCP endpoint. First get the list of potential
- * network layter addresses and transport layer port numbers. Iterate
- * through the returned address list until an attempt to create a
- * listening TCP endpoint is successful (or no other alternative
- * exists).
- */
-
-static int
-tcp_listen(char *port)
-{
-    struct addrinfo hints, *ai_list, *ai;
-    int n, fd = 0, on = 1;
-    
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_flags = AI_PASSIVE;
-    //hints.ai_family = AF_UNSPEC;
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-
-    n = getaddrinfo(NULL, port, &hints, &ai_list);
-    if (n) {
-        fprintf(stderr, "getaddrinfo failed: %s\n",
-                gai_strerror(n));
-        return -1;
-    }
-
-    for (ai = ai_list; ai; ai = ai->ai_next) {
-        fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-        if (fd < 0) {
-            continue;
-        }
-
-        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-        if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
-            break;
-        }
-        close(fd);
-    }
-
-    freeaddrinfo(ai_list);
-
-    if (ai == NULL) {
-        fprintf(stderr, "bind failed for port %s\n",
-                port);
-        return -1;
-    }
-
-    if (listen(fd, 1) < 0) {
-        fprintf(stderr, "listen failed: %s\n", strerror(errno));
-	close(fd);
-        return -1;
-    }
-
-    return fd;
-}
-
-/*
- * Accept a new TCP connection and write a message about who was
- * accepted to the system log.
- */
-
-static int
-tcp_accept(int listen)
-{
-    struct sockaddr_storage ss;
-    socklen_t ss_len = sizeof(ss);
-    char host[NI_MAXHOST];
-    char serv[NI_MAXSERV];
-    int n, fd;
-    fd = accept(listen, (struct sockaddr *) &ss, &ss_len);
-    if (fd == -1) {
-        syslog(LOG_ERR, "accept failed: %s", strerror(errno));
-        return -1;
-    }
-
-    n = getnameinfo((struct sockaddr *) &ss, ss_len,
-                    host, sizeof(host), serv, sizeof(serv),
-                    NI_NUMERICHOST);
-    if (n) {
-        fprintf(stderr, "getnameinfo failed: %s", gai_strerror(n));
-    } else {
-        fprintf(stderr, "connection from %s:%s", host, serv);
-    }
-
-    return fd;
+    int i;
+    printf("Dumping %d bytes (as hex)...\n", len);
+    for (i = 0; i < len; i++)
+	printf("%02hhx", *(data+i));
+    printf("\n");
 }
 
-/*
- * Establish a connection to a remote TCP server. First get the list
- * of potential network layer addresses and transport layer port
- * numbers. Iterate through the returned address list until an attempt
- * to establish a TCP connection is successful (or no other
- * alternative exists).
- */
-
-static int
-tcp_connect(const char *host, const char *port)
-{
-    struct addrinfo hints, *ai_list, *ai;
-    int n, fd = 0, serrs = 0, cerrs = 0;
-    struct timeval tv;
-    
-    memset(&hints, 0, sizeof(hints));
-    //hints.ai_family = AF_UNSPEC;
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-
-    n = getaddrinfo(host, port, &hints, &ai_list);
-    if (n) {
-        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(n));
-        return -1;
-    }
-
-    for (ai = ai_list; ai; ai = ai->ai_next) {
-        fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-        if (fd < 0) {
-            serrs++;
-            continue;
-        }
-
-	tv.tv_sec  = SOCKET_TIMEOUT;
-	tv.tv_usec = 0;
-	setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
-
-        if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
-            break;
-        }
-        cerrs++;
-        close(fd);
-    }
-
-    freeaddrinfo(ai_list);
-
-    if (ai == NULL) {
-        if ((serrs == 1 && ! cerrs) || (!serrs && cerrs == 1)) {
-            fprintf(stderr, "%s: %s\n",
-                    serrs ? "socket" : "connect", strerror(errno));
-        } else {
-            fprintf(stderr, "socket or connect: failed for %s port %s\n",
-                    host, port);
-        }
-        return -1;
-    }
-
-    return fd;
-}
-/*
- * Close a TCP connection. This function trivially calls close() on
- * POSIX systems, but might be more complicated on other systems.
- */
-
-static int
-tcp_close(int fd)
-{
-    return close(fd);
-}
-
-
 int
 main()
 {
     int fd;
+    int new_fd;
     char *msg = "Welcome to catchalld\r\n";
     int n, nwrite, nread;
     int soval = 1;
     int count = 5;
-    char buf[1234];
+
     struct sockaddr_storage from;
     socklen_t fromlen = sizeof(from);
     char host[NI_MAXHOST];
     char serv[NI_MAXSERV];
-    
-    fd = udp_open("1234");
+
+    char buf[BUFLEN];
+    char *bufp;
+    int buflen;
+
+    struct ip *iphdr;
+    struct udphdr *uhdr;    
+    char *payload;    
+    int payload_len;
+    struct sockaddr_in sa1;
+    struct sockaddr_in sa2;
+
+    memset(&sa1, 0, sizeof(sa1));
+    sa1.sin_addr.s_addr = INADDR_ANY;
 
-    if (0 != setsockopt(fd, IPPROTO_UDP, UDP_CATCHALL, &soval, sizeof(soval)))
-	err(EX_UNAVAILABLE, "setsockopt(UDP_CATCHALL) failed");
+    fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+    if (fd < 0)
+	err(EX_OSERR, "Failed to create a raw UDP socket");
     
     while (count > 0) {
-	nread = recvfrom(fd, buf, sizeof(buf), 0,
+	/* wait for traffic */
+	nread = recvfrom(fd, buf, BUFLEN, 0,
 			 (struct sockaddr *) &from, &fromlen);
+	printf("recvfrom() returned %d\n", nread);
 	if (nread < 0) {
 	    warn("recvfrom() returned %d", nread);
 	    continue;
@@ -310,21 +80,79 @@
 	    fprintf(stderr, "received traffic from client %s:%s\n",
 		    host, serv);
 	}
-	
+
 	fprintf(stderr, "traffic on UDP socket \n");
+	bufp = buf;
+	buflen = nread;
+	dump(bufp, buflen);
+
+	/* parse the UDP header */
+	if (nread >= sizeof(struct udphdr)) {
+		/* IP header */
+		iphdr = (struct ip *)bufp;
+		bufp += 20;
+		buflen -= 20;
+		printf("IP hdr: ");
+		dump((void*)iphdr, 20);
+
+		/* UDP header */
+		uhdr = (struct udphdr *)bufp;
+		bufp += sizeof(*uhdr);
+		buflen -= sizeof(*uhdr);
+		printf("UDP hdr: ");
+		dump((void*)uhdr, sizeof(*uhdr));
+		printf("dport: %d, sport: %d\n", 
+		       ntohs(uhdr->uh_dport), ntohs(uhdr->uh_sport));
+		sa1.sin_port = uhdr->uh_dport;
+		memcpy(&sa2, &from, sizeof(sa2));
+		sa2.sin_port = uhdr->uh_sport;
+
+		/* payload */
+		payload = bufp;
+		payload_len = buflen;
+		printf("Payload: ");
+		dump(payload, payload_len);
+		int i;
+		for (i=0; i<payload_len; i++)
+			printf("%c", *(payload+i));
+		printf("\n");
+	} else {
+	    warnx("received packet too short to contain a UDP header\n");
+	}
+
 	n = 0;
 	nwrite = 0;
 	do {
-	    nwrite = sendto(fd, msg + n, strlen(msg) - n, 0,
-			    (struct sockaddr *) &from, fromlen);
+	    //new_fd = udp_open("1234");
+
+	    new_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	    if (new_fd == -1)
+		err(EX_UNAVAILABLE, "socket() failed");
+	    else
+		printf("socket() returned %d\n", new_fd);
+
+	    int nbind =
+		bind(new_fd, (struct sockaddr *)&sa1, sizeof(struct sockaddr));
+	    if (nbind != 0)
+		err(EX_NOHOST, "bind failed");
+	    else
+		printf("bind returned %d\n", nbind);
+
+
+	    nwrite = sendto(new_fd, msg, strlen(msg), 0,
+			    (struct sockaddr *) &sa2, sizeof(sa2));
 	    if (nwrite < 0)
 		warn("sendto() returned %d", nwrite);
 	    else if (nwrite == 0)
 		warnx("sendto() returned %d", nwrite);
+	    else
+		printf("sendto() returned %d\n", nwrite);
+
 	    n += nwrite;
 	} while (n < strlen(msg) && nwrite > 0);
 	count--;
+	close(new_fd);
     }
-    udp_close(fd);
+    close(fd);
     return 0;
 }

==== //depot/projects/soc2007/mharvan-mtund/sys.patches/catchall_tcp_udp/usr_include.patch#2 (text+ko) ====

@@ -8,16 +8,3 @@
  
  #define	TCPI_OPT_TIMESTAMPS	0x01
  #define	TCPI_OPT_SACK		0x02
---- /usr/include/netinet/udp.h.orig	Fri Aug 10 14:25:23 2007
-+++ /usr/include/netinet/udp.h	Fri Aug 10 14:16:35 2007
-@@ -44,4 +44,10 @@
- 	u_short	uh_sum;			/* udp checksum */
- };
- 
-+/*
-+ * User-settable options (used with setsockopt).
-+ */
-+#define UDP_CATCHALL    0x1    /* bind to all unused UDP ports */
-+
-+
- #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708111753.l7BHr9rh075015>