Nmap Development mailing list archives

Re: [Exp PATCH] Send proper UDPLite headers with -sO


From: Kris Katterjohn <katterjohn () gmail com>
Date: Sat, 09 Jun 2007 13:45:24 -0500

I wrote:
I wrote:
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).


Oh yeah, I forgot to verify this: when testing without the patch, I got
no response back whatsoever in relation to the probe (which is the
entire reason behind sending valid headers).

Thanks,
Kris Katterjohn


Hey again,

I have attached a new patch that changes build_udp_raw() to
build_udp_raw_common() (with the bool), and adds a new build_udp_raw()
and build_udplite_raw() which calls the common function so there's no
extra args in build_udp_raw().

Everything still seems to work fine.

Please let me know what you think :)


Thanks,
Kris Katterjohn
Index: tcpip.cc
===================================================================
--- tcpip.cc    (revision 4878)
+++ tcpip.cc    (working copy)
@@ -1663,17 +1663,16 @@
 }
 
 
-/* Builds a UDP packet (including an IP header) by packing the fields
-   with the given information.  It allocates a new buffer to store the
-   packet contents, and then returns that buffer.  The packet is not
-   actually sent by this function.  Caller must delete the buffer when
-   finished with the packet.  The packet length is returned in
-   packetlen, which must be a valid int pointer. */
-u8 *build_udp_raw(struct in_addr *source, const struct in_addr *victim,
-                  int ttl, u16 ipid, u8 tos, bool df,
-                 u8 *ipopt, int ipoptlen, 
-                 u16 sport, u16 dport,
-                 char *data, u16 datalen, u32 *outpacketlen) 
+/* Used by build_udp_raw() and build_udplite_raw() to build
+ * UDP and UDPLite packets
+ */
+static u8 *build_udp_raw_common(struct in_addr *source,
+                               const struct in_addr *victim,
+                               int ttl, u16 ipid, u8 tos, bool df,
+                               u8 *ipopt, int ipoptlen, 
+                               u16 sport, u16 dport,
+                               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);
@@ -1696,7 +1695,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)
@@ -1706,7 +1705,8 @@
 #if STUPID_SOLARIS_CHECKSUM_BUG
   udp->uh_sum = sizeof(struct udp_hdr) + datalen;
 #else
-  udp->uh_sum = magic_tcpudp_cksum(source, victim, IPPROTO_UDP,
+  udp->uh_sum = magic_tcpudp_cksum(source, victim,
+                                  lite ? IPPROTO_UDPLITE : IPPROTO_UDP,
                                   sizeof(struct udp_hdr) + datalen, (char *) udp);
 #endif
   
@@ -1716,13 +1716,47 @@
   }
   
   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;
   return packet;
 }
 
+/* Builds a UDP packet (including an IP header) by packing the fields
+   with the given information.  It allocates a new buffer to store the
+   packet contents, and then returns that buffer.  The packet is not
+   actually sent by this function.  Caller must delete the buffer when
+   finished with the packet.  The packet length is returned in
+   packetlen, which must be a valid int pointer. */
+u8 *build_udp_raw(struct in_addr *source, const struct in_addr *victim,
+                 int ttl, u16 ipid, u8 tos, bool df,
+                 u8 *ipopt, int ipoptlen, 
+                 u16 sport, u16 dport,
+                 char *data, u16 datalen, u32 *outpacketlen) 
+{
+       return build_udp_raw_common(source, victim, ttl, ipid, tos, df,
+                                   ipopt, ipoptlen, sport, dport, data,
+                                   datalen, outpacketlen, false);
+}
+
+/* Builds a UDPLite packet (including an IP header) by packing the fields
+   with the given information.  It allocates a new buffer to store the
+   packet contents, and then returns that buffer.  The packet is not
+   actually sent by this function.  Caller must delete the buffer when
+   finished with the packet.  The packet length is returned in
+   packetlen, which must be a valid int pointer. */
+u8 *build_udplite_raw(struct in_addr *source, const struct in_addr *victim,
+                     int ttl, u16 ipid, u8 tos, bool df,
+                     u8 *ipopt, int ipoptlen, 
+                     u16 sport, u16 dport,
+                     char *data, u16 datalen, u32 *outpacketlen) 
+{
+       return build_udp_raw_common(source, victim, ttl, ipid, tos, df,
+                                   ipopt, ipoptlen, sport, dport, data,
+                                   datalen, outpacketlen, true);
+}
+
 int send_udp_raw( int sd, struct eth_nfo *eth,
                  struct in_addr *source, const struct in_addr *victim,
                  int ttl, u16 ipid,
Index: tcpip.h
===================================================================
--- tcpip.h     (revision 4878)
+++ tcpip.h     (working copy)
@@ -433,11 +433,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,6 +538,13 @@
                  char *data, u16 datalen,
                  u32 *packetlen);
 
+u8 *build_udplite_raw(struct in_addr *source, const struct in_addr *victim,
+                     int ttl, u16 ipid, u8 tos, bool df,
+                     u8* ipopt, int ipoptlen,
+                     u16 sport, u16 dport, 
+                     char *data, u16 datalen,
+                     u32 *packetlen);
+
 /* Builds an ICMP packet (including an IP header) by packing the
    fields with the given information.  It allocates a new buffer to
    store the packet contents, and then returns that buffer.  The
Index: scan_engine.cc
===================================================================
--- scan_engine.cc      (revision 4878)
+++ scan_engine.cc      (working copy)
@@ -2202,6 +2202,14 @@
                               &packetlen);
 
        break;
+      case IPPROTO_UDPLITE:
+       packet = build_udplite_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);
+       break;
       default:
        packet = build_ip_raw(&o.decoys[decoy], hss->target->v4hostip(),
                              pspec->proto,

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: