PERFORCE change 125061 for review
Matus Harvan
mharvan at FreeBSD.org
Sat Aug 11 10:53:10 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125061
Change 125061 by mharvan at 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
More information about the p4-projects
mailing list