From owner-p4-projects@FreeBSD.ORG Sat Aug 11 17:53:10 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 31BE416A421; Sat, 11 Aug 2007 17:53:10 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E244516A41A for ; Sat, 11 Aug 2007 17:53:09 +0000 (UTC) (envelope-from mharvan@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C8A1A13C45B for ; Sat, 11 Aug 2007 17:53:09 +0000 (UTC) (envelope-from mharvan@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7BHr9ZS075018 for ; Sat, 11 Aug 2007 17:53:09 GMT (envelope-from mharvan@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7BHr9rh075015 for perforce@freebsd.org; Sat, 11 Aug 2007 17:53:09 GMT (envelope-from mharvan@FreeBSD.org) Date: Sat, 11 Aug 2007 17:53:09 GMT Message-Id: <200708111753.l7BHr9rh075015@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mharvan@FreeBSD.org using -f From: Matus Harvan To: Perforce Change Reviews Cc: Subject: PERFORCE change 125061 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Aug 2007 17:53:10 -0000 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 #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 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