Nmap Development mailing list archives
Re: [PATCH] Correction to patch to Nping BETA packet recv handler
From: "Luis M." <luis.mgarc () gmail com>
Date: Mon, 24 Aug 2009 12:22:42 +0100
Hi Jack, I've been having a look at your patch. I just added a few more safe checks in getDestAddrFromICMPPacket() to ensure the ip->ip_hl does not contain a bogus value that could produce a segfault, but apart from that it looks great! I've just applied it. Thank you very much, Jack. Best regards, Luis. Jack Grahl wrote:
There was a mistake in the previous patch - instead of ip->len it should of course be ip->hl.
Jack
---------
new patch
---------
--- nping-0.1BETA2/nping.cc 2009-08-20 19:01:10.000000000 +0100
+++ nping-build2/nping.cc 2009-08-22 02:42:32.000000000 +0100
@@ -1661,6 +1661,7 @@
static struct timeval prevtime;
NpingTarget *trg=NULL;
u16 *prt=NULL;
+ u8 proto=NULL;
outPrint(DBG_4, "nping_event_handler(): Received callback of type %s with status %s",
nse_type2str(type), nse_status2str(status));
@@ -1725,27 +1726,54 @@
else
outError(QT_1, "Unsupported EtherType %02X", *ethtype);
- outPrint(VB_0, "RCVD (%.4fs) %s", o.timeSinceStart(t), buffer );
- if( o.getVerbosity() >= VB_3 )
- luis_hdump((char*)packet, packetlen);
- prevtime=pcaptime;
-
- /* Statistics */
- o.stats.addRecvPacket(packetlen);
- trg=o.targets.findTarget( getSrcSockAddrFromIPPacket((u8*)packet, packetlen) );
-
- if( o.getMode()==TCP || o.getMode()==UDP){
- if(trg != NULL){
- prt=getSrcPortFromIPPacket((u8*)packet, packetlen);
- if( prt!=NULL )
- trg->setProbeRecvTCP(*prt, 0);
- }
- }else if (o.getMode()==ICMP){
- if(trg != NULL){
- trg->setProbeRecvICMP(0, 0);
- }
- }
- break;
+ proto = getProtoFromIPPacket((u8*)packet, packetlen);
+
+ if (proto == IPPROTO_UDP || proto == IPPROTO_TCP){
+ /* for UDP/TCP we print out and update the global total straight away
+ since we know that pcap only found packets from connections that we
+ opened */
+ outPrint(VB_0, "RCVD (%.4fs) %s", o.timeSinceStart(t), buffer );
+ if( o.getVerbosity() >= VB_3 )
+ luis_hdump((char*)packet, packetlen);
+ prevtime=pcaptime;
+
+ /* Statistics */
+ o.stats.addRecvPacket(packetlen);
+
+ /* then we check for a target and a port and do the individual stats */
+ trg=o.targets.findTarget( getSrcSockAddrFromIPPacket((u8*)packet, packetlen) );
+
+ if(trg != NULL){
+ prt=getSrcPortFromIPPacket((u8*)packet, packetlen);
+ if( prt!=NULL )
+ trg->setProbeRecvTCP(*prt, 0);
+ }
+
+ }else if (proto==IPPROTO_ICMP){
+ /* we look for a target based on first src addr and second the dest addr of
+ the packet header which is returned in the ICMP packet */
+ trg=o.targets.findTarget( getSrcSockAddrFromIPPacket((u8*)packet, packetlen) );
+ if(trg == NULL){
+ trg=o.targets.findTarget( getDestAddrFromICMPPacket((u8*)packet, packetlen));
+ }
+
+ /* In the case of ICMP we only do any printing and stats if we
+ found a target - otherwise it could be a packet that is nothing
+ to do with us */
+ if(trg!=NULL){
+ outPrint(VB_0, "RCVD (%.4fs) %s", o.timeSinceStart(t), buffer );
+ if( o.getVerbosity() >= VB_3 )
+ luis_hdump((char*)packet, packetlen);
+ prevtime=pcaptime;
+
+ o.stats.addRecvPacket(packetlen);
+
+ trg->setProbeRecvICMP(0, 0);
+ }
+
+ }
+
+ break;
/* In theory we should never get these kind of events in this handler
* because no code schedules them */
diff -u -r nping-0.1BETA2/utils_net.cc nping-build2/utils_net.cc
--- nping-0.1BETA2/utils_net.cc 2009-08-20 19:01:10.000000000 +0100
+++ nping-build2/utils_net.cc 2009-08-22 02:39:10.000000000 +0100
@@ -1360,12 +1360,65 @@
} /* End of getSrcSockAddrFromPacket() */
+struct sockaddr_storage *getDestAddrFromICMPPacket(u8 *pkt, size_t pktLen){
+ static struct sockaddr_storage ss;
+ struct sockaddr_in *s_ip4=(struct sockaddr_in *)&ss;
+ struct ip *i4=(struct ip*)pkt;
+ memset(&ss, 0, sizeof(struct sockaddr_storage));
+ if(pkt==NULL || pktLen < 48)
+ return NULL;
+
+ if( i4->ip_v == 4 ){
+ s_ip4->sin_family=AF_INET;
+ memcpy(&(s_ip4->sin_addr.s_addr), pkt + 24 + i4->ip_hl * 4, 4);
+
+ return &ss;
+ }
+ else {
+ return NULL;
+ }
+
+}
+ /* End of getDestAddrFromICMPPacket */
+
+u8 *getUDPheaderLocation(u8 *pkt, size_t pktLen){
+
+struct ip *i4=(struct ip*)pkt;
+ if(pkt==NULL || pktLen < 40)
+ return NULL;
+
+ /* Packet is IPv4 */
+ if( i4->ip_v == 4 ){
+ if (i4->ip_p == IPPROTO_UDP) {
+ if( pktLen >= ((size_t)(i4->ip_hl*4 + 8)) ) /* We have a full IP+UDP packet */
+ return pkt+(i4->ip_hl*4);
+ }
+ else
+ return NULL;
+ }
+ /* Packet is IPv6 */
+ else if(i4->ip_v == 6 ){
+ if(pktLen<40 + 8 ) /* We possible have a full IPv6+UDP packet */
+ return NULL;
+ if( pkt[6] == IPPROTO_UDP ) /* Next Header is TCP? */
+ return pkt+40;
+ else /* Extension headers not supported, return NULL TODO: support it? */
+ return NULL;
+ }
+ else{
+ return NULL;
+ }
+
+ return NULL;
+}
+ /* end of getUDPheaderLocation */
+
u8 *getTCPheaderLocation(u8 *pkt, size_t pktLen){
struct ip *i4=(struct ip*)pkt;
@@ -1401,6 +1454,30 @@
+/* Returns the IP protocol of the packet or -1 in case of failure */
+u8 getProtoFromIPPacket(u8 *pkt, size_t pktLen){
+struct ip *i4=(struct ip*)pkt;
+static u8 proto;
+
+ if(pkt==NULL || pktLen < 28)
+ return -1;
+
+ /* Packet is IPv4 */
+ if( i4->ip_v == 4 ){
+ proto = i4->ip_p;
+ return proto;
+ }
+
+ /* Packet is IPv6 */
+ else if(i4->ip_v == 6 ){
+ proto = pkt[6];
+ return proto;
+ }
+
+ return -1;
+
+} /* End of getProtoFromIPPacket() */
+
/** @warning Returns pointer to an internal static buffer
@@ -1409,19 +1486,23 @@
static u16 port;
u16 *pnt=NULL;
-u8 *tcp=NULL;
+u8 *header=NULL;
- if(pkt==NULL || pktLen < 40)
+ if(pkt==NULL || pktLen < 28)
return NULL;
- if((tcp=getTCPheaderLocation(pkt, pktLen))==NULL)
- return NULL;
+ if((header=getTCPheaderLocation(pkt, pktLen))==NULL){
+ if ((header=getUDPheaderLocation(pkt, pktLen))==NULL)
+ return NULL;
+
+ }
- pnt=(u16*)&(tcp[0]);
+ pnt=(u16*)&(header[0]);
port= ntohs(*pnt);
-
+
return &port;
+
} /* End of getSrcPortFromIPPacket() */
diff -u -r nping-0.1BETA2/utils_net.h nping-build2/utils_net.h
--- nping-0.1BETA2/utils_net.h 2009-08-20 19:01:10.000000000 +0100
+++ nping-build2/utils_net.h 2009-08-22 02:13:45.000000000 +0100
@@ -129,7 +129,10 @@
int print_dnet_interface(const struct intf_entry *entry, void *arg) ;
int print_interfaces_dnet();
struct sockaddr_storage *getSrcSockAddrFromIPPacket(u8 *pkt, size_t pktLen);
+struct sockaddr_storage *getDestAddrFromICMPPacket(u8 *pkt, size_t pktLen);
+u8 *getUDPheaderLocation(u8 *pkt, size_t pktLen);
u8 *getTCPheaderLocation(u8 *pkt, size_t pktLen);
+u8 getProtoFromIPPacket(u8 *pkt, size_t pktLen);
u16 *getSrcPortFromIPPacket(u8 *pkt, size_t pktLen);
u16 *getDstPortFromIPPacket(u8 *pkt, size_t pktLen);
u16 *getDstPortFromTCPHeader(u8 *pkt, size_t pktLen);
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- [PATCH] Correction to patch to Nping BETA packet recv handler Jack Grahl (Aug 22)
- Re: [PATCH] Correction to patch to Nping BETA packet recv handler Luis M. (Aug 24)
