Logo Search packages:      
Sourcecode: paris-traceroute version File versions  Download package

ICMPReply::ICMPReply ( const uint8 *  packet,
int  packet_len 
)

Create a new ICMPReply from an ICMP packet.

This constructor will initialize up to 4 headers:

  • IPv4 header
  • ICMP header
  • Erroneous IPv4 header
  • Erroneous TCP/UDP/ICMP header

Definition at line 18 of file ICMPReply.cc.

References Datagram::addHeader(), IP4Header::getHeaderLength(), IP4Header::getProtocol(), IP4Header::getTotalLength(), ICMPHeader::getType(), and Datagram::setData().

                                                         {
  // Get the IP4 header
  IP4Header* ip4 = new IP4Header(packet, packet_len, 0);
  addHeader(ip4);

  // Check the protocol, should be ICMP
  if (ip4->getProtocol() != 1)
    throw TrException(str_log(ERROR, "Reply should be ICMP datagram"));
  
  int ip4_hdrlen = ip4->getHeaderLength();
    
  // Get the ICMP header
  ICMPHeader* icmp = new ICMPHeader(packet, packet_len, ip4_hdrlen);
  addHeader(icmp);

  // Case of a Port Unreachable or Time Exceeded ICMP Message
  if (icmp->getType() == 0x0b || icmp->getType() == 0x03) {
    // Get the IP header of the erronous message
    IP4Header* err_ip4 = new IP4Header(packet, packet_len, ip4_hdrlen + 8);
    addHeader(err_ip4);

    int ip_remaining_len = ip4->getTotalLength() - 8 - 128;
    //printf("remain len %d bytes\n", ip_remaining_len);
#if defined __NetBSD__ || __FreeBSD__

#else

    ip_remaining_len -= ip4_hdrlen;

#endif // __NETBSD__

    // If the protocol is UDP, get the UDP header.
    if (err_ip4->getProtocol() == 17) {
      UDPHeader* err_udp = new UDPHeader(packet, packet_len, ip4_hdrlen + 28);
      addHeader(err_udp);
      // Check if there is an ICMP MPLS extension
      if (ip_remaining_len > 0) {
        MPLSHeader* mpls = new MPLSHeader(packet, ip_remaining_len, ip4_hdrlen + 8 + 128);
        addHeader(mpls);
      }
    // Else if the protocol is ICMP, get the ICMP header
    } else if (err_ip4->getProtocol() == 1) {
       ICMPHeader* err_icmp = new ICMPHeader(packet, packet_len, 48);
       addHeader(err_icmp);
       // Check if there is an ICMP MPLS extension
       if (ip_remaining_len > 0) {
         MPLSHeader* mpls = new MPLSHeader(packet, ip_remaining_len, ip4_hdrlen + 8 + 128);
         addHeader(mpls);
       }
    // Else set the last height bytes as RAW data
    } else if (err_ip4->getProtocol() == 6) {
       ICMPHeader* err_icmp2 = new ICMPHeader(packet, packet_len, ip4_hdrlen + 28);
       //printf("adding header\n");
       addHeader(err_icmp2);
       //printf("done\n");
       // Check if there is an ICMP MPLS extension
       if (ip_remaining_len > 0) {
         //printf("adding MPLS\n");
         MPLSHeader* mpls = new MPLSHeader(packet, ip_remaining_len, ip4_hdrlen + 8 + 128);
         addHeader(mpls);
       }
       setData(packet + ip4_hdrlen + 28, 8);
    }
    
    else {
       setData(packet + ip4_hdrlen + 28, 8);
    }
  }
}


Generated by  Doxygen 1.6.0   Back to index