mirror of
https://github.com/nmap/nmap.git
synced 2025-12-08 13:41:29 +00:00
Rewrite is_response_icmp to give access to the encapsulated packet.
We will want to also get the ICMP ID from the packet. Remove the now-unused getDestAddrFromICMPPacket function.
This commit is contained in:
@@ -1491,14 +1491,46 @@ char *ProbeMode::getBPFFilterString(){
|
||||
* we might have sent. Returns non-NULL target pointer if found. Otherwise
|
||||
* returns NULL. */
|
||||
static NpingTarget *is_response_icmp(const unsigned char *packet, unsigned int packetlen) {
|
||||
const void *data;
|
||||
unsigned int datalen;
|
||||
struct abstract_ip_hdr packethdr;
|
||||
NpingTarget *trg;
|
||||
|
||||
trg = o.targets.findTarget(getSrcSockAddrFromIPPacket((u8*)packet, packetlen));
|
||||
if (trg == NULL) {
|
||||
trg = o.targets.findTarget(getDestAddrFromICMPPacket((u8*)packet, packetlen));
|
||||
/* Parse the outermost IP header (for its source address). */
|
||||
datalen = packetlen;
|
||||
data = ip_get_data(packet, &datalen, &packethdr);
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
trg = o.targets.findTarget(&packethdr.src);
|
||||
if (trg != NULL)
|
||||
return trg;
|
||||
|
||||
/* If that didn't work, check if this is ICMP with an encapsulated IP
|
||||
header. */
|
||||
if (packethdr.proto == IPPROTO_ICMP) {
|
||||
struct ip *ip;
|
||||
unsigned int iplen;
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
|
||||
|
||||
if (datalen < 8)
|
||||
return NULL;
|
||||
ip = (struct ip *) ((char *) data + 8);
|
||||
iplen = datalen - 8;
|
||||
/* Make sure there is enough header to have a dest address. */
|
||||
if (iplen < 20)
|
||||
return NULL;
|
||||
if (ip->ip_v != 4)
|
||||
return NULL;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr = ip->ip_dst;
|
||||
trg = o.targets.findTarget(&ss);
|
||||
|
||||
return trg;
|
||||
}
|
||||
|
||||
return trg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1259,36 +1259,6 @@ struct sockaddr_storage *getSrcSockAddrFromIPPacket(u8 *pkt, size_t pktLen){
|
||||
} /* 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;
|
||||
struct ip *orig_i4=NULL;
|
||||
memset(&ss, 0, sizeof(struct sockaddr_storage));
|
||||
|
||||
if(pkt==NULL || pktLen < 48) /* 48 = First IP hdr + ICMP pkt + Embedded IP hdr */
|
||||
return NULL;
|
||||
|
||||
if( i4->ip_v == 4 ){
|
||||
/* Let's make sure we can trust i4->ip_hl field. We just check if we
|
||||
* have enough bytes to access the DST Addr of the original IP header that
|
||||
* is included in the ICMP packet. */
|
||||
if ( (size_t)(i4->ip_hl*4 + 8 + 16 + 4) > pktLen )
|
||||
return NULL;
|
||||
/* Let's make sure the ICMP pkt contains an IPv4 packet */
|
||||
orig_i4=(struct ip*)( pkt + (8 + i4->ip_hl*4) );
|
||||
if( orig_i4->ip_v != 4 )
|
||||
return NULL;
|
||||
s_ip4->sin_family=AF_INET;
|
||||
memcpy(&(s_ip4->sin_addr.s_addr), pkt + i4->ip_hl*4 + 8 + 16, 4);
|
||||
return &ss;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
} /* End of getDestAddrFromICMPPacket */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ int send_packet(NpingTarget *target, int rawfd, u8 *pkt, size_t pktLen);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user