Internetworking 1 - The Basics about IPv4, ICMP and IGMP ******************************************************** [ Copyright (C) 2003 by rattle ] [ http://www.awarenetwork.org/ ] __________ [ Contents ] ŻŻŻŻŻŻŻŻŻŻ ::[0] Intro ::[1] The Internet Protocol Version 4 :.. : ::(1.1) The IPv4 Header : ::(1.2) Fragmentation : ::[2] Internet Control Message Protocol :.. : ::(2.1) The ICMP Header : :.. : : ::{2.1.1} Echo : : ::{2.1.2} Destination Unreachable : : ::{2.1.3} Source Quench : : ::{2.1.4} Redirect : : ::{2.1.5} Time Exceeded : : ::{2.1.6} Parameter Problem : : ::{2.1.7} Address Mask : : : ::[2.2] Traceroute : ::[2.3] Ping : ::[3] Internet Group Management Protocol :.. : ::(3.1) Mutlticasting && Groups : ::(3.2) The IGMP Header : ::(3.3) The IGMP Bug : ::[A] Networking Byte Order ::[B] Bits && Bytes :.. : :: (B-1) Binary Calculations : :: (B-2) Units && Values : ::[C] DoD Reference Model : ::[4] Further Reading ::[5] Last Words ___ _______ [ 0 ] :: [ Intro ] ŻŻŻ ŻŻŻŻŻŻŻ Peace to all the Windows survivors in the Linux-dominated world of computer security! So, what is this tutorial about - it is about the low level aspects of communication between computers, especially across the internet. This will not yet cover all aspects and all layers of networking and network traffic and I will not explain any kind of transport protocol such as TCP or UDP here, this paper is actually about IP. I plan to continue this paper by writing a tutorial abot the Transport layer, about IPv6 and about how to use raw sockets in Windows 2000 and Windows XP. However, I realized that fundamental knowledge about IP is important for a good understanding of networking in general, and since I haven't seen many indepth papers yet, I decided to write one. This is not ment for total experts, neither is it ment for total newbies. You should have an average knowledge of high level networking, coding in C and that's about it. I won't let you write a device driver or similar stuff. If you think you are not ready to read this, just buy a good book and learn some basic C/C++ coding at first. Then dig the internet for some basic tutorials on IP addressing, routing, subnets and some common protocols like HTTP just to get the idea. If you think you are to l337 to read this, go play hide and go fuck yourself. Be sure to check [Appendix B] whenever you do not understand the relation of bits, bytes, words and dwords. [Appendix A] is required for better understanding of the code samples that will follow. [Appendix C] is also a very important appendix since I will often refer to different networking layers in the tutorial. You should definitely check the appendixes at first if you are not familliar with their contents. ___ _________________________________ [ 1 ] :: [ The Internet Protocol Version 4 ] ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ The internet protocol version 4 is the current standard, and it's the most basic protocol that we, as a software developer, can make use of. IP is what actually brings the data from one computer to another one. As a Protocol, "it" is responsible for addressing and delivery. Saying that the protocol itself does this is not really easy to understand, and it's not really correct anyway. Not the protocol, but the routers all over the globe transport the data by applying the internet protocol. It's basically like this: You send a packet of data with an internet protocol header (which will be discussed later) and the next router routes this packet by the information he finds in the IP header. After some hops from one router to the next one, your packet finally reaches its destination. I already mentioned it, IP has a header just like any hight-level protocol that you know. And honestly, it's the only thing we should care about in this tutorial. _____ _________________ ( 1.1 ) : ( The IPv4 Header ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ The IP header works in the same way all headers of all protocols work - it gives some information about the exchange of information. If you send data, you first send the header which contains this information and afterwards, the actual data follows. Pictures help the human mind to understand a certain matter better, and since the presentation within the RFC's sucks, I thought I would make yet another ASCII visualization of the IP header: <-------------------------------------------- Bits ---------------------------------------------> _______________________________________________________________________________________________ |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| |ŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Version | Length | Type Of Service | Total Length | |___________|___________|_______________________|_______________________________________________| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Identification | Flags | Fragment Offset | |_______________________________________________|________|______________________________________| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Time To Live | Protocol | Header Checksum | |_______________________|_______________________|_______________________________________________| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Source Address | |_______________________________________________________________________________________________| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Destination Address | |_______________________________________________________________________________________________| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Options | Padding | |_______________________________________________________________________|_______________________| |###############################################################################################| |###########################################[ Data ]############################################| |###############################################################################################| ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ (Figure 1.1.1: The IP Header Format as explained in RFC 791, part 3.1: http://www.rfc-editor.org/rfc/rfc791.txt) Every little box with a number in it stands for one binary digit. The version, for example, has 3 binary digits and since this is an IPv4 tutorial, these 4 digits will always be "0100" in our examples since "100" is "4" in decimal. As always, refer to [Appendix B] if you feel mentally threatened by the word "bit". Here's a brief explaination of all the differen header fields: Version ~~~~~~~ The version field contains the version number of the internet protocoll currently used. The current standard is version 4, but due to its disadvantages concerning the ammount of available addresses, security problems, complicated system configuration and several other issues, the new IPv6 will be made global standard soon I think. Interne Header Length - IHL ~~~~~~~~~~~~~~~~~~~~~~~~~~~ This value defines the length of the actual header (not the data body), expressed as a multiple of 4. Why 4? Because 4 bytes are one double word and the IP header always ends on such a double word boundary. This field is required since the length of the header can vary due to the possibility of adding options. The smallest valid value is 5, which means 20 bytes (5*4=20), in this case, no options are set. By adding options, the header lenght can grow to up to 60 Byte (maximum value for the IHL field: 15) Type of Service - TOS ~~~~~~~~~~~~~~~~~~~~~ The TOS field defines the service requested by an IP - datagram. This field allows you to specify, how the routers have to deal with your precious packet once you sent it. This is very usefull when sending data over large networks but unfortunately, most commercial products do not support the TOS field at all or only by using a tacky implementation. Have a look at the picture of the complete IP header (Figure 1.1.1), this is where you will find the TOS Ocet (Ocet: eight values, or eight bits). Here is a more detailed representation: _______________________________________________________ | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Complete TOS Ocet within IP Header | |_______________________________________________________| And this is what the Ocet itself looks like, if we have a closer look at it: _______________________________________________________ | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Precedence | D | T | R | MBZ | |____________________|______|______|______|_____________| (Figure 1.1.2 - The TOS Ocet) The Precedence -field consists of 3 bits which can have the following, different meanings: +--------+---------+------------------------+ | Binary | Decimal | Description | +--------+---------+------------------------+ | 000 | 0 | Routing | | 001 | 1 | Priority | | 010 | 2 | Immediate | | 011 | 3 | Flash | | 100 | 4 | Flash Override | | 101 | 5 | Critical | | 110 | 6 | Internetwork Control | | 111 | 7 | Network Control | +--------+---------+------------------------+ D stands for delay, and if it is set to 1, the delay is being minimized. T stands for throughput and if it is set to 1, the throughput is being maximized. Finally, R stands for reliability, and setting it to 1 maximizes the reliability. The MBZ Bits stand for "must be zero" and that says it all - these are reserved values that have to be zero and which were planned to be used for further implementations ... I don't think that these reserved values will be used at any time in any way for any new implementation since IPv6 already has a completely different header structure, but that's only my opinion. I hate reserved values. Total Length ~~~~~~~~~~~~ This is the total length of the complete datagram to be sent. It includes the length of the IP header and the length of all the data that follows the IP header, including headers of high-level protocols. A computer has to be capable of receiving and handling packets with a length of 576 bytes, datagrams that are larger than that have to be fragmented in order to be delivered correctly. (See (1.2) for more information about fragmented packets) Identification ~~~~~~~~~~~~~~ This is a unique number which allows the destination host to find out what packet belongs to which datagram so that he can reassemble the single packets to form the complete datagram he received. All fragmented packets of one datagram have the same identification number, which is set by the sender. Flags ~~~~~ This field is 3 bits long, the first bit is reserved and not used in any implementation yet, to my knowledge. Did I ever mention I hate reserved values?? Anyway, the second two bits determine whether a packet is fragmented and/or may be fragmented. The field is structured as follows: ____________________ | 01 | 02 | 03 | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻ| | Res. | DF | MF | |______|______|______| The DF bit stands for "don't fragment" and prevents packets from being fragmented at all if it is set to 1. The MF bit stands for "more fragments" and is set in all but the last packet in the sequence of fragments which are to be reassembled by the destination host. Fragment Offset ~~~~~~~~~~~~~~~ When a datagram has been fragmented, the destination host has to reassemble the fragmened packets to get the data. "Well", you will say, "he can identify them by the identification flag to put them together". Yeah, but in what order? Imagine you recevie a text document over the web and your computer just puts the packets together randomly, then you would certainly not be able to read it, eh? Well the Fragment Offset is just a number that specifies to which position, relative to the beginning of the complete datagram, this packet belongs. All fragments except the last one have to be a multible of 8 bytes in size - This is the elementary fragment unit. I did not make this up, this is an open standard and I have no idea why it is exactly 8 bytes and not 4. Check [Appendix B] TTL - Time To Live ~~~~~~~~~~~~~~~~~~ Remember how packets reach their destination host? They get routed through to it by being sent from one router to the next one, over a couple of nodes all over the globe. Now sometimes packets get lost, and if they wouldn't be discarded somehow and sometime, they would forever be roaming about in the world wide web. Thus, the TTL flag was implemented to represent the time that a packet has until it will be discarded. By definition, the TTL value represents the number of seconds that a packet has until it will die [RFC791]. Every node that routes the packet has to decrease the value by at least one. If the packet remains stored in this node for a longer time, the value has to be decreased multiple times. Of course, the packet is discarded once the value reaches 0. The sender of the packet will be informed about a discarded packet by an ICMP message. [RFC1700] defines a default value of 64. [RFC791] - http://www.rfc-editor.org/rfc/rfc791.txt [RFC1700] - http://www.rfc-editor.org/rfc/rfc791.txt Protocol ~~~~~~~~ This flag contains the number of the transport protocol that follows this IP header - IP only performst the most basic task of sending and routing the datagram, the transport layer has to use this service provided by IP and perform the next task. For example, IP does not guarantee that all packets reach their destination - the underlaying transport protocol TCP (transmission control protocol) ensures that all data that reaches the destination host is the same that has been sent by the sender. Not all transport protocols do ensure this, and if you want to know more about the whole achitecture and how the different layers interact with each other, please refer to [Appendix C]. So anyway, you will deal with TCP in most cases, although I will also explain the ICMP and IGMP (yehaw, the famous windows IGMP bug!) protocols in this tutorial. For all up-to-date Protocol names and related values, refer to the homepage of the Internet Assigned Numbers Authority: http://www.iana.org/ Some common values: +----------+---------+-------------+------------------------------------+ | Binary | Decimal | Protocol | Detailed Description | +----------+---------+-------------+------------------------------------+ | 00000001 | 1 | ICMP | Internet Contol Message Protocol | | 00000010 | 2 | IGMP | Internet Group Management Protocol | | 00000110 | 6 | TCP | Transmission Control Protocol | | 00010001 | 17 | UDP | User Datagram Protocol | +----------+---------+-------------+------------------------------------+ All Values: +----------+---------+-------------+------------------------------------+ | Binary | Decimal | Protocol | Detailed Description | +----------+---------+-------------+------------------------------------+ | 00000001 | 1 | ICMP | Internet Contol Message Protocol | | 00000010 | 2 | IGMP | Internet Group Management Protocol | | 00000011 | 3 | GGP | Gateway-to-Gateway Protocol | | 00000101 | 5 | ST | Stream | | 00000110 | 6 | TCP | Transmission Control Protocol | | 00000111 | 7 | UCL | UCL | | 00001000 | 8 | EGP | External Gateway Protocol | | 00001001 | 9 | IGP | Interior Gateway Protocol | | 00001010 | 10 | BNN-RCC-MON | BBN RCC Monitoring | | 00001011 | 11 | NVP-II | Network Voice Protocol | | 00001100 | 12 | PUP | PUP | | 00001101 | 13 | ARGUS | ARGUS | | 00001110 | 14 | EMCON | EMCON | | 00001111 | 15 | XNET | Cross Net Debugger | | 00010000 | 16 | CHAOS | Chaos | | 00010001 | 17 | UDP | User Datagram Protocol | | 00010010 | 18 | MUX | Multiplexing | | 00010011 | 19 | DCN-MEAS | DCN Measurement Subsystems | | 00010100 | 20 | HMP | Host Monitoring Protocol | | 00010101 | 21 | PRM | Packet Radio Measurement | | 00010110 | 22 | XNS-IDP | XEROX NS IDP | | 00010111 | 23 | TRUNK-1 | Trunk 1 | | 00011000 | 24 | TRUNK-2 | Trunk 2 | | 00011001 | 25 | LEAF-1 | Leaf 1 | | 00011010 | 26 | LEAF-2 | Leaf 2 | | 00011011 | 27 | RDP | Reliable Data Prococol | | 00011100 | 28 | IRTP | Internet Reliable Transaction | | 00011101 | 29 | ISO-TP4 | ISO Transport Protocol Class 4 | | 00011110 | 30 | NETBLT | Bulk Data Transfer Protocol | | 00011111 | 31 | MFE-NSP | MFE Network Services Protocol | | 00100000 | 32 | MERIT-INP | MERIT Internodal Protocol | | 00100001 | 33 | SEP | Sequential Exchange Protocol | | 00111110 | 62 | CFTP | CFTP | | 01000000 | 64 | SAT-EXPAK | SATNET and backroom EXPAK | | 01000001 | 65 | MIT-SUBNET | MIT subnet support | | 01000010 | 66 | RVD | MIT Remote Virtual Disk Protocol | | 01000011 | 67 | IPPC | Internet Pluribus Packet Core | | 01000101 | 69 | SAT-MON | SATNET Monitoring | | 01000111 | 71 | IPCV | Internet Packet Core Utility | | 01001100 | 76 | BR-SAT-MON | Backroom SATNET Monitoring | | 01001110 | 78 | WB-MON | WIDEBAND Monitoring | | 01001111 | 79 | WB-EXPAK | WIDEBAND EXPAK | +----------+---------+-------------+------------------------------------+ Header Checksum ~~~~~~~~~~~~~~~ From the Free Online Dictionary of Computing (http://foldoc.doc.ic.ac.uk/foldoc/index.html, 01/25/2003) "A computed value which depends on the contents of a block of data and which is transmitted or stored along with the data in order to detect corruption of the data. The receiving system recomputes the checksum based upon the received data and compares this value with the one sent with the data. If the two values are the same, the receiver has some confidence that the data was received correctly. " The checksum field contains the 16-bit one's complement of the one's complement sum of the whole datagram including IP header. For computing the checksum, the checksum field is first set to zero. So basically, the checksum is a pain in the ass since you have to calculate it ABSOLUTELY correct depending on the datagram you are about to send if you want that your packet reaches its destination. The algorithm for calculating a checksum looks like this: unsigned short CalculateChecksum( const unsigned short *usBuf, int iSize ) { unsigned long usChksum=0; while (iSize>1) { usChksum += *usBuf++; iSize -= sizeof(unsigned short); } if (iSize) usChksum += *(unsigned char*)usBuf; usChksum = (usChksum >> 0x10) + (usChksum & 0xffff); usChksum += (usChksum >> 0x10); return (unsigned short)(~usChksum); } Update on February the 17th, 2004: I wrote a checksum function in python which I would like to add here. Python has some amazing advantages for building custom packets (by using the struct module, for instance): from types import * def EnsureInt(c): if (type(c)==StringType): return ord(c[0]) else: return int(c) def checksum(buffer): chk = 0; iter = 0 while (iter <= (len(buffer)-2)): chk += EnsureInt(buffer[iter]) << 8 chk += EnsureInt(buffer[iter+1]) iter += 2 if (iter!=len(buffer)): chk += EnsureInt(buffer[iter]) chk = (chk>>0x10)+(chk&0xFFFF) chk += (chk>>0x10) return ((~chk)&0xFFFF); Source IP Address ~~~~~~~~~~~~~~~~~ That's the IP that sends the data - yep, the sender defines this value. And this is the point where IP spoofing is theoretically possible: We just change the value to anything we want. What? Sample source code? Be patient, there's some source code later. Now IP spoofing has a major problem when the transport protocol is more complex (like TCP) - In this case, you will not get any reply since the IP that you are sending the datagram to will reply to the spoofed IP address you have set in this field of the header. Well, in some cases, we do not need to get any reply, though ... Destination IP Address ~~~~~~~~~~~~~~~~~~~~~~ Contains the IP Address of the computer that the datagram will be sent to. Some Info about IP addresses: You probably know IP Addresses as they are written in the dotted decimal notation, eg: 192.168.0.1 Now wtf is this in binary, what will this look like in an IP header? That's actually quite simple: 192 is 11000000 in binary. 168 is 10101000 in binary. 0 is 00000000 in binary. 1 is 00000001 in binary. => 192.168.0.1 is 11000000.10101000.00000000.00000001 in binary. => leaving out the dots, we get: 11000000101010000000000000000001 I think you got the point. This binary value can be expressed as a decimal number as well btw, but I am too lazy to calculate that. Options ~~~~~~~ This flag was added to provide the possibility of adding more different information to the IP header which was not part of the original IP header dessign. The option field has a variable length, it is NOT always 24 bits long. Options are an interesting topic, but I do not think that they are of any interest for this tutorial. You will certainly find detailed information on options on the web. _____ _______________ ( 1.2 ) : ( Fragmentation ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ I have talked a lot about this whole fragmentation stuff, but what does it actually mean? To ensure that a datagram can be sent across any type of network, the Internet Protocl has to suit the packet size to the respective network. Every kind of network has its own maximum packet size (Maximum Transfer Unit - MTU), which defines the maximum size for packets that are to be sent through the network. For instance, the MTU of X.25 networks is 128 bytes, and an ethernet-packet may not be larger than 1500 bytes. If the MTU of the network is smaller than the size of the datagram, then the datagram has to be fragmented. However, it is not sufficiant that the transport layer (TCP) uses smaller packets - a packet on its way from the source host to its destination will be routed thought different networks with different MTU's. Because of that, a more flexible mechanism which allows fragmentation at the IP level is necessary. Well, and this mechanism is called fragmentation ;D. Fragmentation means that ever single router on this globe has to be able to fragment and reassemble received packets. ___________________________________________________________________ | | | | IP-Header | Data | |_____________|_____________________________________________________| / /| | \ / / | | \ / / | | \ ___________/__________/ |______________________| _____________________\ | |##########| | |##########| | |##########| | IP-Header |#Fragment#| | IP-Header |#Fragment#| | IP-Header |#Fragment#| | |##########| | |##########| | |##########| ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ (Figure 1.2.1: Fragmentation sheme) Every fragment of a framgented datagram contains its own, complete IP header. By using the identification field, all packets can be recognized as part of the originating datagram. Each of the respective packets can indeed use different ways to get from the sender to the destination host. Thus, the Fragment Offset field of the IP header was implemented to indicate at what position relative to the beginning of the complete datagram the respective fragment is located. ___ __________________________________________ [ 2 ] :: [ ICMP - Internet Control Message Protocol ] ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Besides the Internet Protocol, there are some additional protocols at the lower level. One of these is the Internet Control Message Protocol, ICMP, which is used for notification and error messages. ICMP's are always sent embedded to an IP datagram. ICMP is mainly used for information purpose, but sometimes it is also used for checking whether a host is reachable, this is known as ping. The complete ICMP protocol is a very flexible protocl with many options and even fields that can contain miscellaneous data. Therefore, ICMP can also be used as a "tunnel" to transmit information that it was not intended to be used for. However, this technique (obviously called "ICMP tunneling") has not been a real issue to the computer security world, since network layer firewalls are able to simply block all ICMP requests reaching a network from the outside. And since ICMP is not offering any necessary services like TCP does, it can merely be ignored. ICMP is not a transport layer protocol, but it is sent encapsulated within an IP Datagram: ____________________________________________________________ | |#######################################| | IP-Header |# Datagram Data #######################| | |#######################################| ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ ^ ^ | | |_______________________________________| | |#########################| | ICMP-Header |# ICMP-Data #############| | |#########################| ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ (Figure 2.0.1: Encapsulation of ICMP messages) Refer to [Appendix C] for information about "layers" and the complete DoD Reference Model. _____ _________________ ( 2.1 ) : ( The ICMP Header ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ ICMP is an error reporting and diagnostic utility - it is considered a required part of any IP implementation. Since the information carried by the ICMP message is always different, according to the big ammount of possible ways of use, the underlaying structure of the ICMP header is always the same, although the respective fields have a very variable meaning. Remember this representation of ICMP is relative to the ammount of bytes used for each field, not to the ammount of bits. Refer to [Appendix B]. <------------------------ Bytes ------------------------> - - - - - - - - - - - - - - - - > __________________________________________________________________________________________ | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ | Type | Code | Checksum | Miscellaneous | Optional Variable Appendix |______|______|_____________|___________________________|__________________________________ (Figure 2.1.1: A generalized ICMP Header) ICMP Type ~~~~~~~~~ The type of the message defines what the message is actually about, it gives broad information about what has happened. Possible values are: +------+--------------------------------+ | 0 | Echo reply | | 3 | Destination unreachable | | 4 | Source Quench | | 5 | Redirect | | 8 | Echo | | 9 | Router advertisement | | 10 | Router solicitation | | 11 | Time exceeded | | 12 | Parameter problem | | 13 | Time-Stamp request | | 14 | Time-Stamp reply | | 15 | Information request (obsolete) | | 16 | Information reply (obsolete) | | 17 | Address mask request | | 18 | Address mask reply | | 30 | Traceroute | | 31 | Datagram conversion error | | 32 | Mobile host redirect | | 33 | IPv6 Where-Are-You | | 34 | IPv6 I-Am-Here | | 35 | Mobile registration request | | 36 | Mobile registration reply | | 37 | Domain name request | | 38 | Domain name reply | | 39 | SKIP | | 40 | Photuris | +------+--------------------------------+ ICMP Code ~~~~~~~~~ The meaning of this value depends on the ICMP type. For instance, in an Echo or Echo reply message, the code is always 0 and has no meaning whereas in a "Destination unreachable" message, it can specify a more detailed error code. I will discuss most of the possible ICMP messages and replies later which will include explainations of the respective Codes. Checksum ~~~~~~~~ This is the same checksum as IP uses, calculated in the same way and the same pain in the ass. It is calculated by calculating the 16-bit one's complement of the one's complement sum of the whole ICMP message, excluding the IP header, of course. For computing the checksum, the checksum field is first set to zero. Miscellaneous ~~~~~~~~~~~~~ Well, the contents of this field once again differ, depending on the type of message sent. The Echo and Echo reply messages, for instance, split this field up into two words that specify a uinque identifier and a sequence number. Other ICMP messages don't use this miscellaneous data at all, it's once again a completely variable field - however, it is included in all ICMP message, in contrast to the optional appendix. If the miscellaneous data is not used, the field is set to zero. Optional Variable Appendix ~~~~~~~~~~~~~~~~~~~~~~~~~~ Depending on the ICMP message, the Miscellaneous field can be expanded to include more information. In some cases, this field contains the IP header of the datagram that caused the message and further 64 bits of it's data, to give the receiver of the control message better possibilities to process the error. In other cases that will be discussed later, it is used for completely different purposes. As you can see, ICMP can be used for a lot of different purposes. Because of that, I listed several ways of use, along with the according ICMP header structure below. You do not have to read these sections for a better understanding of networking as whole, but it might come in handy when programming actual applications which apply ICMP functions such as Echo. Also remember that I did not include all possible ICMP messages to this list - if you are interested in the messages that were not included, please refer to other sources, you should find enough information on the net by using any search engine. And if nothing helps, drop me an email and I will try to help good as possible. _______ ______ { 2.1.1 } · { Echo } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻ Echo and Echo Reply messages are used to examine the speed of a certain network and also if a certain host is reachable or not. A host is often examined by using an ICMP Echo message before the client connects, this way he can be sure that the host is available. These days, ICMP can be blocked by firewalls and thus, Echo is not a clear indicator for the availability of a certain host. However, most servers still support the complete variety of ICMP messages sufficiantly, of course. To perform an Echo examination, the client computer sends an ICMP Echo message - ICMP Type 8. Once the Echo request reaches the server computer, it replies by sending an ICMP Echo Reply (ICMP Type 0) message to the client computer. The Identification field is used for a clear and unique identification of the process that sent the message. Under windows, you can quite simply apply the return value of this macro to the Identification field: #define GETPROCID_16 ((unsigned short)(GetCurrentProcessId()&0xFFFF)) The client computer numbers the Echo Requests that he sends sequentially. The server that replies to an Echo Request uses exactly the same Sequence number when sending the appropriate Echo Reply. This way, the client computer can check the correctness of the reply easiely. The remaining part of the ICMP datagram contains variable data, which usually consists of characters like "1234567890". However, the size of this variable data can be changed to about any value which can be used to examine the behavious of a network in relation to differently sized packets sent through it. <------------------------ Bytes ------------------------> - - - - - - - - - - - - - - - - > __________________________________________________________________________________________ | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ | Type | Code | Checksum | Identifier | Sequence | Optional Data .... |______|______|_____________|_____________|_____________|__________________________________ Types: Codes: +-------+-----------------------------------+ +-------+----------------------------------+ | value | meaning | | value | meaning | +-------+-----------------------------------+ +-------+----------------------------------+ | 8 | Echo | | 0 | Only possible value | | 0 | Echo Reply | +-------+----------------------------------+ +-------+-----------------------------------+ _______ _________________________ { 2.1.2 } · { Destination Unreachable } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ The name says it all - whenever any sort of IP datagram, no matter what underlaying protocol or data it contains, cannot be routed through to the destination host specified in the destination IP address field, this ICMP message is generated and sent to the origin of the message. Since there are a lot of possible reasons why a packet cannot be delivered, the unreachable message has the largest ammount of possible code parameters as far as I know. The Destination Unreachable ICMP message does not use the Miscellaneous field and thus, the field is set to zero. The Variable Appendix of the ICMP message is used to include the IP header and 64 bits of data belonging to the packet that could not be delivered. - The ICMP header is 8 bytes long. - The IP header has a length of 5 dwords, thats ((5 * 32) = 160) bits or ((160 / 8) = 20) bytes. - 64 bits of further data equal 8 bytes, just if you have problems with the figure below. Refer to [Appendix B] => The complete Destination Unreachable ICMP message has a length of (8+8+20) or 36 bytes which equals 288 bits. <---------------------------------------------------- Bytes --------------------------------------> _________________________________________________________________________________________________ | | | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | 36 | | | | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Unused (Must be Zero) | IP header + 8 more bytes .... | |______|______|_____________|___________________________|_________________________________________| Types: +-------+----------------------------------------------------------+ | value | meaning | +-------+----------------------------------------------------------+ | 3 | Destinatiopn Unreachable | +-------+----------------------------------------------------------+ Codes: +-------+----------------------------------------------------------+ | value | meaning | +-------+----------------------------------------------------------+ | 0 | Network Unreachable | | 1 | Host Unreachable | | 2 | Protocol Unreachable | | 3 | Port Unreachable | | 4 | Fragmentation needed but Don't Fragment (DF) bit was set | | 5 | Source Route Failed | | 6 | Dest. Network Unknown | | 7 | Dest. Host Unknown | | 8 | Source Host Isolated (obsolete) | | 9 | Destination Network administratively prohibited | | 10 | Destination Host administratively prohibited | | 11 | Network unreachable for this Type Of Service | | 12 | Host unreachable for this Type Of Service | | 13 | Communication prohibited by filter | | 14 | Host precedence violation | | 15 | Precedence cutoff in effect | +-------+----------------------------------------------------------+ _______ _______________ { 2.1.3 } · { Source Quench } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Sometimes, a router's resources are not sufficiant to route a certain load of data. This usually happens when a computer sends data from a fast network through a slower one to the destination network or when several different routers are sending their datagrams through a single router - the router cannot process the packets fast enough. Once this overflow exceeds the entire resources of such a router, the router starts to discard packets. For each discarded packet, the router sends a Source Quench ICMP message to the sender of the datagram. The sender regulates the ammount of packets sent according to the Source Quench messages he receives. The main problem of this mechanism is the fact that these ICMP messages themselves use the routers resources and thus they are hardly being used these days. The packet flow regulation is commonly a task of the transport layer. Refer to [Appendix C] <---------------------------------------------------- Bytes --------------------------------------> _________________________________________________________________________________________________ | | | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | 36 | | | | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Unused (Must be Zero) | IP header + 8 more bytes .... | |______|______|_____________|___________________________|_________________________________________| Types: Codes: +-------+-------------------------------------+ +-------+-------------------------------------+ | value | meaning | | value | meaning | +-------+-------------------------------------+ +-------+-------------------------------------+ | 4 | Source Quench - Only possible value | | 0 | Only possible value | +-------+-------------------------------------+ +-------+-------------------------------------+ _______ __________ { 2.1.4 } · { Redirect } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻ When a router receives an IP packet that cannot be routed to its destination since the router can't reach the destination network for some reason, the packet has to be sent by using a different route. The router that notices the problem usually knows a correct route for the packet to be used instead, and in this case, it sends an ICMP Redirect message to the sender of the packet informing him about the correct route. The sender can now send the packet throught the correct router to the destination network. "Correct route" is a bit optimistic in this case - imagine you would simply (well, this should me more or less simple) spoof an ICMP Redirect message to a certain computer which tells this computer to use your IP as the correct router. This is a possible way to establish spoofed connections, launch Man In The Middle attacks and similar stuff. The topic of spoofing could fill a tutorial itself, so I won't go indepth here ... The Redirect Header also includes the IP header and the first 64 bits of the datagram that caused the message, refer to {2.1.2} for calculations regarding the resulting ICMP message size. <---------------------------------------------------- Bytes --------------------------------------> _________________________________________________________________________________________________ | | | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | 36 | | | | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Router IP Address | IP header + 8 more bytes .... | |______|______|_____________|___________________________|_________________________________________| Types: +-------+----------------------------------------------------------------------------+ | value | meaning | +-------+----------------------------------------------------------------------------+ | 5 | Redirect | +-------+----------------------------------------------------------------------------+ Codes: +-------+----------------------------------------------------------------------------+ | value | meaning | +-------+----------------------------------------------------------------------------+ | 0 | Redirect all datagrams directed to this network | | 1 | Redirect all datagrams directed to this host | | 2 | Redirect all datagrams with this Type Of Service, directed to this network | | 3 | Redirect all datagrams with this Type Of Service, directed to this host | +-------+----------------------------------------------------------------------------+ _______ _______________ { 2.1.5 } · { Time Exceeded } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Whenever an IP datagram cannot be delivered because the Time To Live of the packet exceeded or because the reassembly of the packet fragment exceeded a certain time limit, the ICMP Time Exceeded message is sent to the origin of the packet that caused the problem. There are several reasons for such an event, including the procedure of generating packets with very low TTL values by intent - this method is used for traceroute applications. Refer to (2.2). <---------------------------------------------------- Bytes --------------------------------------> _________________________________________________________________________________________________ | | | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | 36 | | | | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Unused (Must be Zero) | IP header + 8 more bytes .... | |______|______|_____________|___________________________|_________________________________________| Types: Codes: +-------+-------------------------------------+ +-------+-------------------------------------+ | value | meaning | | value | meaning | +-------+-------------------------------------+ +-------+-------------------------------------+ | 11 | Time Exceeded - Only possible value | | 0 | Time To Live (TTL) exceeded | +-------+-------------------------------------+ | 1 | Fragment reassembly took too long | +-------+-------------------------------------+ _______ ___________________ { 2.1.6 } · { Parameter Problem } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ This ICMP message informs the sender when the IP header of a datagram contains an error and when this datagram had to be discarded due to this problem. A pointer (Ptr.) is included to the ICMP header that defines the position of the Ocet (byte) within the IP header where the error was found. <---------------------------------------------------- Bytes --------------------------------------> _________________________________________________________________________________________________ | | | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | .... | 36 | | | | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Ptr. | Unused (Zero) | IP header + 8 more bytes .... | |______|______|_____________|______|____________________|_________________________________________| Types: Codes: +-------+-------------------------------------+ +-------+-------------------------------------+ | value | meaning | | value | meaning | +-------+-------------------------------------+ +-------+-------------------------------------+ | 12 | Parameter Problem | | 0 | unspecified error | +-------+-------------------------------------+ | 1 | required option missing | +-------+-------------------------------------+ _______ ______________ { 2.1.7 } · { Address Mask } ŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ This ICMP message is used by computers within large networks to receive their subnet mask. In this case, A client computer sends an ICMP Address Mask Request (ICMP Type 17) to the router with a unique sequence number and am empty Address Mask field (set to zero). The router then replies to the message with an ICMP Address Mask Reply message that contains the Address Mask and the same sequence number that the client had chosen. The function of the Identifier field is, once again, to identify the process that sent the ICMP message. Refer to {2.1.1} since the fields are used in the same way when sending an Echo Request / Reply. <--------------------------------------------- Bytes -------------------------------> ___________________________________________________________________________________ | | | | | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | | | | | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Identifier | Sequence | Address Mask | |______|______|_____________|_____________|_____________|___________________________| Types: Codes: +-------+-------------------------------+ +-------+-------------------------------+ | value | meaning | | value | meaning | +-------+-------------------------------+ +-------+-------------------------------+ | 17 | Address Mask Request | | 0 | Only possible value | | 18 | Address MAsk Reply | +-------+-------------------------------+ +-------+-------------------------------+ _____ ____________ ( 2.2 ) : ( Traceroute ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻ Traceroute is a tool that does what the name already indicates - it traces the complete route a packet takes from you to a destination host you specify. This feature can be expanded to what some of you might already know as a visual traceroute, a traceroute program that also derives geographical information from the IP Address of each node that the packets run through. So, how does it work? Quite simple. A traceroute application sends packets to a port on the remote machine that does not exist. These packets are send with an increasing TTL (Time To Live), starting at a value of 1. So, when the first packet (which has a TTL of 1) reaches the first node, it's TTL is reduced by one and becomes zero: The packet is discarded. Now an ICMP message is generated from the node that discarded the packet which informs you (the sender of the packet) that the packet was discarded. This message will be a "Time exceeded" message with a code of 0 (this means that the Time To Live of a packet expired). Once the traceroute application receives this ICMP message, it knows the IP Address of the node. After having stored this value, the next packet is sent with an increased value for the TTL field. This way, the traceroute application is informed about each router that the packets run through since every node sends an ICMP message when the packet is discarded which contains the routers address within the IP header. However, once the packet reaches the target computer, a "Destination unreachable" message is generated with a code of 3 (which means "Port unreachable"). This way, the traceroute application knows that the route is finished and notes the origin of this ICMP message as the last host. It's IP should equal the IP of the host that had to be traced. Traceroute is available on most systems as a commandline application. For Windows 2000, call cmd.exe and type "tracert [host]". _____ ______ ( 2.3 ) : ( Ping ) ŻŻŻŻŻ ŻŻŻŻŻŻ Ping has a rather simple concept. A ping application sends an ICMP message with type 8 and code 0 to the target host. The target host will reply to this packet by copying its contents completely and only setting the type to 0 (Echo Reply) - provided that he is set up to reply to ICMP messages, which can be blocked by most modern firewalls. Now once the ping application receives the reply, the ping is done. Ping usually starts a timer once the first packet is sent and displays the time that the packet needed to reach the remote host and return. That's about it. ___ ___________________________________________ [ 3 ] :: [ IGMP - Internet Group Management Protocol ] ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ IGMP is a protocol which was invented to manage host groups within networks that support multicasting. If you already know what multicasting and host groups are, you don't have to read the next part since it will only discuss these very basics. _____ ________________________ ( 3.1 ) : ( Multicasting && Groups ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ There are currently three ways to send a packet - unicast, broadcast and multicast. I will give a brief explaination of the first two methods, and then I will tell you why multicasting is better. While discussing this topic, keep in mind that we are talking about situations where it is required to send a set of information not only to one single remote host, but to many computers within the same network. A good example is a network with one centralized server performing a certain task that reports its status to several other servers which relay on this information while processing their own tasks. Unicast is the most primitive way to achieve this - it means that the information is sent to each respective machine that relays on the information, ony by one. Sending a broadcast datagram basically means that the server sends sends the information once, but the data will reach every computer within a complete network. The respective computers within the network then have to decide themselves if they need this data or not. Of course, this means that the sender saves a lot of resources as he only has to send the data once with the nice effect that all computers within a network will receive it. While Unicast consumes a lot of the sender's resources, broadcast messages consume the resources of the complete network in a horrible way. Multicast is a solution that combines the advantages of both systems, in a way. A multicast message is sent to a certain "host group" within the network once. All members of this group will receive the message, respectively. Group membership is not static, the respective computers have to be able to join and leave groups dynamically. For this purpose, IGMP was invented for the IPv4 protocol to manage group membership within modern networks with multicasting support. For more informationm refer to the following RFC's: Host Extensions for IP Multicasting: http://www.rfc-editor.org/rfc/rfc1112.txt (intro & pages 1-3 are important for you) Multicast Transport Protocol: http://www.rfc-editor.org/rfc/rfc1301.txt (read it only if you became curious) _____ _________________ ( 3.2 ) : ( The IGMP Header ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ The IGMP Header actually does not differ from the ICMP Header very much. It looks like this: <------------------------ Bytes ------------------------> _______________________________________________________ | | | | | | | | | | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | | | | | | | | | | |ŻŻŻŻŻŻ|ŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻ|ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Type | Code | Checksum | Group Address | |______|______|_____________|___________________________| (Figure 5: The IGMP Header) Regarding Figure 5: I refer to the newer definition of the IGMP header, as it is presented by the IANA (Internet Assigned Numbers Authority): "The Internet Group Message Protocol (IGMP) has many messages that are identified by a 'type' field. Note that the original definition of IGMP in [RFC1112] divided this field into two 4-byte values, 'version' and 'type'. This was decided to be too restrictive, so the fields were combined into a single 8-bit type space." (http://www.iana.org/assignments/igmp-type-numbers [02/09/03]) IGMP Type ~~~~~~~~~ Similar to ICMP, this field defines what the message is actually about. Possible Values are: +------+------+---------+-------------------------------+------------+ | Dec. | Hex | Binary | Name | Reference | +------+------+---------+-------------------------------+------------+ | 17 | 0x11 | 0010001 | IGMP Membership Query | [RFC1112] | | 18 | 0x12 | 0010010 | IGMPv1 Membership Report | [RFC1112] | | 19 | 0x13 | 0010011 | DVMRP | [RFCDVMRP] | | 20 | 0x14 | 0010100 | PIM version 1 | [PIMv1] | | 21 | 0x15 | 0010101 | Cisco Trace Messages | | | 22 | 0x16 | 0010110 | IGMPv2 Membership Report | [RFC2236] | | 23 | 0x17 | 0010111 | IGMPv2 Leave Group | [RFC2236] | | 23 | 0x17 | 0010111 | IGMPv2 Leave Group | [RFC2236] | | 30 | 0x1E | 0011110 | Multicast Traceroute Response | [Fenner] | | 31 | 0x1F | 0011111 | Multicast Traceroute | [Fenner] | | 34 | 0x22 | 0100010 | IGMPv3 Membership Report | [RFC3376] | +------+------+---------+-------------------------------+------------+ IGMP Code ~~~~~~~~~ Some of the IGMP messages also contain a certain code that gives more detailed information about what event the message is indicating. Currently, only DVMRP and PIM Version 1 have Codes at all, though: +--------+-------+-----------------------+ | Type | Code | Meaning | +--------+-------+-----------------------+ | DVMRP | 1 | Probe | | DVMRP | 2 | Route Report | | DVMRP | 3 | Old Ask Neighbors | | DVMRP | 4 | Old Neighbors Reply | | DVMRP | 5 | Ask Neighbors | | DVMRP | 6 | Neighbors Reply | | DVMRP | 7 | Prune | | DVMRP | 8 | Graft | | DVMRP | 9 | Graft Ack | +--------+-------+-----------------------+ | PIM V1 | 0 | Query | | PIM V1 | 1 | Register | | PIM V1 | 2 | Register-Stop | | PIM V1 | 3 | Join/Prune | | PIM V1 | 4 | RP-Reachable | | PIM V1 | 5 | Assert | | PIM V1 | 6 | Graft | | PIM V1 | 7 | Graft Ack | | PIM V1 | 8 | Mode | +--------+-------+-----------------------+ Checksum ~~~~~~~~ This is the same checksum as ICMP uses, calculated almost exactly the same way this time. The 16-bit one's complement of the one's complement sum of the whole IGMP message is calculated, excluding the IP header. For computing the checksum, the checksum field is first set to zero, as always. Group Address ~~~~~~~~~~~~~ Also explained in [RFC1112] on page 2. A host groupt within a network has its own class D IP address. Converting this to the commonly used dotted decimal notation of IP addresses, host group addresses range from 224.0.0.0 to 239.255.255.255 where the address 244.0.0.0 is never used and 244.0.0.1 represents the "permanent group of all IP hosts". Basically, this is an identifier for the group that a certain computer is member of. It is used to address all computers within a host group. _____ ______________ ( 3.3 ) : ( The IGMP Bug ) ŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Also known as the "Kiss of Death", a vulnerability within the processing mechanism of fragmented IGMP packets was found in Windows 9x and also Windows 2000. The effects of an attempt to reassemble the packet are a crash within the TCP/IP stack of windows which forces dialup users to reconnect to their ISP, while TCP network users will have to reboot their computer entirely. Sometimes, the attack also results in blue or completely freezed screens. In this case, the user will be able to press return and continue his work with the computer - however, the machine will not be able to receive data from the internet. Indeed, the machine will still be able to send data, but it cannot receive packets any more. Actually, it's no effort to exploit the bug at all. The problem occurs even with correctly fragmented packets - the first exploit for this problem which would compile with any windows compiler that I saw did not even use raw sockets to modify the IP or IGMP header, it merely sent a very big IGMP packet to the remote host which would then be automatically be fragmented by the kernel since it was too large to send it through the network without further fragmentation. So, the interesting fact about this bug is this very matter - we can send a fully valid IGMP packet to a windows PC and merely due to the fragmentation, the remote computer crashes. I have not yet seen any information about what happens within the TCP/IP stack of windows to cause such a problem, but I also believe that there is no such information available. I saw a tcpdump log that shows a kod attack on some website I can't remember, and it looks like this: 15:53:37.899412 12.13.14.15 > localhost: (frag 48648:200@14800) 15:53:37.901212 12.13.14.15 > localhost: (frag 48648:1480@13320+) 15:53:37.901392 12.13.14.15 > localhost: (frag 48648:1480@11840+) 15:53:37.901534 12.13.14.15 > localhost: (frag 48648:1480@10360+) 15:53:37.901681 12.13.14.15 > localhost: (frag 48648:1480@8880+) 15:53:37.901828 12.13.14.15 > localhost: (frag 48648:1480@7400+) 15:53:37.901972 12.13.14.15 > localhost: (frag 48648:1480@5920+) 15:53:37.902117 12.13.14.15 > localhost: (frag 48648:1480@4440+) 15:53:37.902262 12.13.14.15 > localhost: (frag 48648:1480@2960+) 15:53:37.902401 12.13.14.15 > localhost: (frag 48648:1480@1480+) 15:53:37.902541 12.13.14.15 > localhost: igmp-0 [v0][|igmp] (frag 48648:1480@0+) ____________ _______________________ [ Appendix A ] :: [ Networking Byte Order ] ŻŻŻŻŻŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ When sending an IP datagram, all information within this datagram is stored in Big Endian format. If you know what this means, you can stop reading this part since it's all you need to know. However, you might as well have no idea about the terms "Big Endian" and "Little Endian" - in this case, I will try to explain it to you. It is actually not complicated but you should be familliar with the expressions for many of the code samples and for a better understanding. Due to whatever strange reason, two different architectures for handling memory storage are used when dessiging computers and Operating Systems. These two architectures were called "Big Endian" and "Little Endian". These terms were derived from the phrases "Big End In" and "Little End In" and they specify the way in which bytes (not bits) are ordered when being stored in memory. On an Intel computer, the little end is stored first - this means a hexadecimal word like 0x1234 is stored in memory as two blocks: 0x34 and 0x12. The little end, or lower end, is stored first. Here is another example for a dword: 0x12345678 would be stored as 0x78 0x56 0x34 0x12. "Big End In" does this in the reverse fashion, so 0x1234 would be stored as 0x12 0x34 in memory. Now Windows 2k was designed around Little Endian architecture, whereas IP datagrams use the Big Endian architecture. If you have already coded with sockets, you should be familliar with the functions htons, ntohs, htonl and ntohl - these functions convert from one architecture to the other one. This little piece of code helps a lot in my opinion: #ifdef WIN32 #ifndef BIG_ENDIAN #define LITTLE_ENDIAN #endif #endif #if defined(BIG_ENDIAN) #define NETWORK_ORDER_16(__x) htons(__x) #define NETWORK_ORDER_32(__x) htonl(__x) #define HOST_ORDER_16(__x) (__x) #define HOST_ORDER_32(__x) (__x) #elif defined(LITTLE_ENDIAN) #define NETWORK_ORDER_16(__x) (__x) #define NETWORK_ORDER_32(__x) (__x) #define HOST_ORDER_16(__x) ntohs(__x) #define HOST_ORDER_32(__x) ntohl(__x) #else #error Could not determine Byte Order. #endif // overloaded functions for greater comfort: DWORD BigEndian(DWORD ipField) { return NETWORK_ORDER_32(ipField); } WORD BigEndian(WORD ipField) { return NETWORK_ORDER_16(ipField); } DWORD LittleEndian(DWORD ipField) { return HOST_ORDER_32(ipField); } WORD LittleEndian(WORD ipField) { return HOST_ORDER_16(ipField); } ____________ _______________ [ Appendix B ] :: [ Bits && Bytes ] ŻŻŻŻŻŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Well it's really some fundamental stuff, but I thought I might include it as an appendix to make sure that this paper is as complete as possible. A bit is the most basic unit, and it is the only unit that computers actually understand. A bit can be either one or zero, plus or minus - a bit only has two states. You say that a bit is "set" when it's value is 1, and the bit is "not set" when the bit's value is zero. Since bits only have two possible values, calculations based on bits are always based on binary number systems. ___ ___________________ (B-1) : (Binary Calculations) ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ How do you calculate in binary? It is actually quite easy, and I will illustrate it by showng you a small sample - We want to know the decimal value of 10111: +---------+---+---+---+---+---+ | Bits: | 4 | 3 | 2 | 1 | 0 | +---------+---+---+---+---+---+ | Values: | 1 | 0 | 1 | 1 | 1 | +---------+---+---+---+---+---+ Bit 0 (is set): (2 ^ 0) * 1 = 1 Bit 1 (is set): + (2 ^ 1) * 1 = 2 Bit 2 (is set): + (2 ^ 2) * 1 = 4 Bit 3 (not set): + (2 ^ 3) * 0 = 0 Bit 4 (is set): + (2 ^ 4) * 1 = 16 ------------------- 23 The decimal value of 10111 is 23. The difference between decimal and binary is merely the base - in binary, the base is 2 and in decimal, it's 10. Decimal: You count 0,1,2,3,4,5,6,7,8,9 and now you have to add another digit: 10. Binary: You count 0,1 and now you already have to add another digit: 10 +---------+---------+ | Decimal | Binary | +---------+---------+ | 0 | 0 | | 1 | 1 | | 2 | 10 | | 3 | 11 | | 4 | 100 | | 5 | 101 | | 6 | 110 | | 7 | 111 | | 8 | 1000 | | 9 | 1001 | | 10 | 1010 | +---------+---------+ ___ _______________ (B-2) : (Units && Values) ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ We cannot only rely on the numbers one and zero in modern computing, we need larger units. We get those by simply using blocks of bits if we need larger numbers, and the commonly smallest block used by a programmer is the byte. It consists of 8 bits and thus, its largest possible value is 11111111 - which is (100000000-1) and that's ((2^8)-1), which is 256-1, which means that the largest possible value for a byte in decimal is 255. Actually, this is the largest value for an ASCII char, and this should ring a bell. Indeed, one single character is also one single byte. Other values that you should know are: 1 byte = 8 bits 1 word = 2 bytes = 16 bits 1 dword = 4 bytes = 32 bits (double word) ____________ _________________________ [ Appendix C ] [ The DoD Reference Model ] ŻŻŻŻŻŻŻŻŻŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ The US Department of Defense (DoD) developed in the beginning of the seventies a reference model for internetwork communication between computers. This was way before the OSI model was developed and I honestly don't care about the OSI model since it has no practical use. The DoD reference model consists of four layers: |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Application Layer | |________________________________| | | | Transport Layer (Host-to-Host) | |________________________________| | | | Internet Layer | |________________________________| | | | Network Layer (Physical) | |________________________________| (Figure C-1: The DoD reference model) Every layer uses the services provided by the underlaying layer. It is the common idea of interfaces - every layer uses these services without knowing how the underlaying layer performs the task. In real life, IP performs the task of the Internet Layer and TCP represents the Transport Layer - and this combination is a horrible violation of the protocol hirachy, in fact. This will be elaborated in the following tutorial. The different layers communicate with each other by their vertical order as described in Figure C-1, but the logical communication between two computers is performed between the same layer respectively: [ Host 1 ] [ Router ] [ Host 2 ] |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| | Application Layer | <=================================> | Application Layer | |_________||_________| |_________/\_________| || || |ŻŻŻŻŻŻŻŻŻ\/ŻŻŻŻŻŻŻŻŻ| |ŻŻŻŻŻŻŻŻŻ||ŻŻŻŻŻŻŻŻŻ| | Transport Layer | <=================================> | Transport Layer | |_________||_________| |_________/\_________| || || |ŻŻŻŻŻŻŻŻŻ\/ŻŻŻŻŻŻŻŻŻ| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| |ŻŻŻŻŻŻŻŻŻ||ŻŻŻŻŻŻŻŻŻ| | Internet Layer | <===> | Internet Layer | <===> | Internet Layer | |_________||_________| |___________________| |_________/\_________| || || |ŻŻŻŻŻŻŻŻŻ\/ŻŻŻŻŻŻŻŻŻ| |ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ| |ŻŻŻŻŻŻŻŻŻ||ŻŻŻŻŻŻŻŻŻ| | Network Layer | <===> | Network Layer | <===> | Network Layer | |____________________| |___________________| |____________________| (Figure C-2: Communication between two computers) When information is transmitted from one host to another one, this information is always information that is of importance for an application, running on both hosts. The application layer now takes the information and gives it to the Transport Layer - the Transport Layer now adds its Header information to the beginning of the information and gives the complete new package of Header+Data to the Internet Layer. The Internet Layer adds its own Header to the beginning of the complete package as well and the Network Layer which receives this package also adds its own header. This process is called Encapsulation. The complete package is now send across the net, routed by different routers and finally reaches the destination host. Once this host receives this complete package, the different layers respectively remove their header by evaluating the information contained within it and give the remaining data to the overlaying layer. ___ _________________ [ 4 ] :: [ Further Reading ] ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ I am going to continue this paper by writing an appropriate tutorial about the Transport Layer and about how to implement the use of raw sockets in a windows applicaiton. However, at the point of time when I published this paper here, no other paper by me about the topic existed and thus I want to provide some links and possibilities for further reading. First of all, do buy a good book if you want to learn about really complex stuff. One single book about TCP/IP will give you a lot of background and you should find one in your language at the local book store. Another thing is reading the RFC's I referred to within the tutorial. The RFC's are an essential source of information for anyone who is interested in networking issues. However, you might want to read a bit more light stuff that explains some basic theory first - if this is what you want, check this article from neworder about "The very basics of TCP/IP - Layers and what they do.": http://neworder.box.sk/newsread.php?newsid=6319 Also make sure to check other papers like this from the neworder links archieve: http://neworder.box.sk/codebox.links.php?key=tcpgui An interesting little paper about IPv6 which might be interesting after having read an IPv4 tutorial can be found here: http://www.garykessler.net/library/ipv6_exp.html However, you should definitely continue reading about the transport layer as it is the layer that follows the IP layer described within this tutorial particularly: http://www.etcs.ipfw.edu/~lin/cpet355/S2000/Lectures/UDP-TCP_files/frame.htm http://www-net.cs.umass.edu/kurose/transport/UDP.html http://www-net.cs.umass.edu/kurose/transport/congestion.html And, since some of you might actually want to code a packet sniffer, a SYN scanner or similar tools - check out the great TCP/IP library from komodia. It is an extremely large, open-source, object-oriented library that supports windows developers with anything that they might need to code applications that make use of raw sockets. However, I would suggest you to dig the source code and try to understand it instead of simply using the interface. That helps a lot. http://www.komodia.com/tools.htm And, since some of the links might be dead when you read this or since I might have already published the next few parts of this series - do use your brain and a search engine to find more information yourself. ___ ____________ [ 5 ] :: [ Last Words ] ŻŻŻ ŻŻŻŻŻŻŻŻŻŻŻŻ Well, I am about to continue this paper by writing another one about the Transport Layer, maybe a special one about spoofing (ARP-spoofing, ICMP Redirect spoofing) and similar stuff. However, this tutorial represents the fundamentals required to understand most of the other topics that might follow and whether or not I will continue this as a series depends on the feedback that I will get. If only few people understood this tutorial or if it was written badly, any attempt to continue it would be sneseless. So, just tell me what you think and also give me advice if you think I could make this or that feature better by using different words or elaborating something that I left out. For in time, sit back, relax and taste the real thing. Yours, rattlesnake@box.sk