Nmap Development mailing list archives

[Exp PATCH] Send proper UDPLite headers with -sO


From: Kris Katterjohn <katterjohn () gmail com>
Date: Mon, 23 Apr 2007 11:41:46 -0500

Hey everyone,

I attached a patch (SVN /nmap-exp/kris r4662) that send proper UDPLite
(RFC 3828) headers with the IPProto Scan.

I remember reading the RFC for this protocol sometime in 2005, and
thought it would catch on faster than it has.  The Linux kernel added
support for it in 2.6.20.  Ethereal/Wireshark has dissectors for it.
I've read that it has been used quite a bit with streaming audio, video,
games and VoIP with no problems.

So, do you think this protocol is "important" enough to send valid
headers with when doing -sO?  I actually wrote up a patch a while back
(well, I guess it was actually a long time ago) to add this, but didn't
think it was "big" enough yet.  Now that Linux added it, and I've read
that more people are using it, I'm sending this to you guys :)

I've tested it:  I get ICMP Port Unreachables when scanning localhost
(Linux 2.6.20.7), and ICMP Protocol Unreachables when scanning my
gateway (which doesn't support it).

About the patch:
Since UDP and UDPLite are so similar, I just added a boolean flag in
build_udp_raw() to signify using UDPLite (it's false by default, so no
need changing udp code using this function).

The length field of the UDP packet is now the checksum coverage field in
UDPLite.  It's technically supposed to be 0 in UDPLte when the whole
packet is covered by the checksum, so that's why that part is there
(even though I see no reason why placing the whole length in the field
would break anything).

Thanks,
Kris Katterjohn

P.S. Whew, that was a longer email than I originally intended :)
Index: tcpip.cc
===================================================================
--- tcpip.cc    (revision 4661)
+++ tcpip.cc    (revision 4662)
@@ -1642,7 +1642,7 @@
                   int ttl, u16 ipid, u8 tos, bool df,
                  u8 *ipopt, int ipoptlen, 
                  u16 sport, u16 dport,
-                 char *data, u16 datalen, u32 *outpacketlen) 
+                 char *data, u16 datalen, u32 *outpacketlen, bool lite) 
 {
   int packetlen = sizeof(struct ip) + ipoptlen + sizeof(struct udp_hdr) + datalen;
   u8 *packet = (u8 *) safe_malloc(packetlen);
@@ -1665,7 +1665,7 @@
   udp->uh_sport = htons(sport);
   udp->uh_dport = htons(dport);
   udp->uh_sum   = 0;
-  udp->uh_ulen  = htons(sizeof(struct udp_hdr) + datalen);
+  udp->uh_ulen  = lite ? 0 : htons(sizeof(struct udp_hdr) + datalen);
   
   /* We should probably copy the data over too */
   if (data)
@@ -1675,8 +1675,10 @@
 #if STUPID_SOLARIS_CHECKSUM_BUG
   udp->uh_sum = sizeof(struct udp_hdr) + datalen;
 #else
-  udp->uh_sum = magic_tcpudp_cksum(source, victim, IPPROTO_UDP,
-                                  sizeof(struct udp_hdr) + datalen, (char *) udp);
+  udp->uh_sum = magic_tcpudp_cksum(source, victim,
+                                  lite ? IPPROTO_UDPLITE : IPPROTO_UDP,
+                                  sizeof(struct udp_hdr) + datalen,
+                                  (char *) udp);
 #endif
   
   if ( o.badsum ) {
@@ -1685,7 +1687,7 @@
   }
   
   fill_ip_raw(ip, packetlen, ipopt, ipoptlen,
-       tos, ipid, df?IP_DF:0, myttl, IPPROTO_UDP,
+       tos, ipid, df?IP_DF:0, myttl, lite ? IPPROTO_UDPLITE : IPPROTO_UDP,
        source, victim);
   
   *outpacketlen = packetlen;
Index: tcpip.h
===================================================================
--- tcpip.h     (revision 4661)
+++ tcpip.h     (revision 4662)
@@ -435,11 +435,15 @@
 };
 #endif /* HAVE_STRUCT_ICMP */
 
-/* Some systems might not have this */
+/* Some systems might not have these */
 #ifndef IPPROTO_IGMP
 #define IPPROTO_IGMP 2
 #endif
 
+#ifndef IPPROTO_UDPLITE
+#define IPPROTO_UDPLITE 136
+#endif
+
 /* Prototypes */
 /* Converts an IP address given in a sockaddr_storage to an IPv4 or
    IPv6 IP address string.  Since a static buffer is returned, this is
@@ -534,7 +538,7 @@
                  u8* ipopt, int ipoptlen,
                  u16 sport, u16 dport, 
                  char *data, u16 datalen,
-                 u32 *packetlen);
+                 u32 *packetlen, bool lite = false);
 
 /* Builds an ICMP packet (including an IP header) by packing the
    fields with the given information.  It allocates a new buffer to
Index: scan_engine.cc
===================================================================
--- scan_engine.cc      (revision 4661)
+++ scan_engine.cc      (revision 4662)
@@ -2198,6 +2198,14 @@
                               sport, o.magic_port,
                               o.extra_payload, o.extra_payload_length, 
                               &packetlen);
+       break;
+      case IPPROTO_UDPLITE:
+       packet = build_udp_raw(&o.decoys[decoy], hss->target->v4hostip(),
+                              o.ttl, ipid, IP_TOS_DEFAULT, false,
+                              o.ipoptions, o.ipoptionslen,
+                              sport, o.magic_port,
+                              o.extra_payload, o.extra_payload_length, 
+                              &packetlen, true);
 
        break;
       default:

Attachment: signature.asc
Description: OpenPGP digital signature


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org

Current thread: