This practice aims to implement the lower levels of the TCP / IP protocol stack. Specifically, the link level will be constructed, which in this case will be implemented using the Ethernet protocol.

computer science

Description

Introduction

This practice aims to implement the lower levels of the TCP / IP protocol stack. Specifically, the link level will be constructed, which in this case will be implemented using the Ethernet protocol. The ARP protocol will be implemented on the Ethernet level, which will allow us to perform translations between network level and link level addresses. Both protocols will be used in the following practice to implement the network level (IP in our case).



Next we will analyze the Ethernet and ARP headers. We can obtain the description of headers requested in their respective RFCs (here in Spanish:  http://www.rfc-es.org/ ) or standards ( http://www.ieee802.org/3/ )


Ethernet  (IEEE 802.3 Ethernet):

Ethernet is a protocol used in data transmissions in local area networks (LAN). The basic unit of transmission in this protocol is the frame or  frame . Next we will analyze the format of the header of an Ethernet frame:


ETH


Fields:

  • Destination Address (6 bytes):  Ethernet or MAC address corresponding to the receiver of the frame. If its value is FF: FF: FF: FF: FF: FF is a plot diffusion ( broadcast ) which is addressed to all computers on the local network.
  • Source Address (6 bytes):  Ethernet or MAC address corresponding to the sender.
  • Ethernet or  Ethertype type (2 Bytes):  numeric identifier that indicates which upper level protocol is encapsulated in the current Ethernet frame. The typical values ​​that we are going to handle for this practice are 0x0800 (IP) and 0x0806 (ARP). Other types are reflected in the following document:  http://standards.ieee.org/develop/regauth/ethertype/eth.txt .


The Ethernet header occupies 14 bytes and then we find the payload or  payload  of the frame. This payload consists of the header and contents of the higher level protocol specified in the Ethernet type. 


Frame sizes:

  • The minimum size of an Ethernet frame is 60 bytes (excluding the CRC, which is generated on the network card). If the size of the Ethernet header plus the content you want to send is less than this limit is added padding ( padding ) to complete the 60 bytes. Typically the padding consists of bytes with the value 0.
  • The maximum size of a standard Ethernet frame is 1514 bytes (again excluding the CRC, which is generated on the network card). There are larger frames called  Jumbo Frames  that will not be used in these practices. For the purposes of these practices, if the size of the Ethernet header plus the content to be sent is greater than 1514, we will assume that sending is not possible.



ARP (RFC 826):


ARP is a protocol that allows us to perform translations between network level addresses and link level addresses. In our case we will translate IP addresses (for example 192.168.1.1) to Ethernet addresses (for example 00: AB: CD: EF: 11: FF) within a local network. This protocol is a fundamental piece of communication networks because when sending data from one device to another we use IP addresses while at the link level we will need to use (typically) Ethernet addresses. 


General operation:


When a team wants to know what is the Ethernet address associated with a specific IP address:

  1. Send a request ( Request ) ARP on broadcast (with destination Ethernet address = FF: FF: FF: FF: FF: FF) in which you specify your Ethernet and IP address and also specify which IP address you want to resolve. For example, if device A (whose MAC is 00: 00: 00: 00: 00: 01 and IP 192.168.1.1) wants to know what is the MAC address of device B (which has IP 192.168.1.2), it will send a packet to all equipment (broadcast) asking "who has the IP 192.168.1.2? Answer 192.168.1.1 with MAC 00: 00: 00: 00: 00: 01". 
  2. As this ARP packet reaches all the computers in the local network, when it reaches device B (with IP 192.168.1.2 and MAC 00: 00: 00: 00: 00: 02) that device will generate an ARP response ( Reply ). This answer   will NOT be broadcast because knowing the IP and MAC address of the questioning team can answer individually ( Unicast ). The ARP reply packet will answer "Address 192.168.1.2 is at 00: 00: 00: 00: 00: 02".
  3. The response packet will arrive at the A device that will extract the information and determine that the MAC associated with IP 192.168.1.2 is 00: 00: 00: 00: 00: 02.


It is generally expected that a response will be received for a request made. There is a special case of ARP request called  Free ARP  that teams perform when initializing their network stack. This request consists of asking for the IP address itself. Typically, no one is expected to answer that request and if someone answers it is determined that the IP itself is in use by other equipment.

To avoid repeating ARP requests in a short period of time, an ARP cache with a timer is typically used. In this way, if we want to make an ARP resolution and find an entry in the cache we get the data there. Otherwise we make the request and if we receive an answer we add the response to the cache for future reference.

Headboard:



The ARP protocol has a fixed header that will not depend on the link level or the network level and a specific one. As in practice we will only translate IP addresses to Ethernet addresses, the following shows the particular ARP header for the combination of Ethernet link addresses and IP network addresses:


ARP


Fields:

  • Hardware Type (2 Bytes):  Indicates the type of link level addresses. In the case of Ethernet addresses this value is 0x0001.
  • Protocol Type (2 Bytes):  Indicates the type of network level addresses. In the case of IP addresses this value is 0x0800.
  • Hardware Size (1 Byte):  Size (in bytes) of link level addresses. In the case of Ethernet this field must be worth 6.
  • Protocol Size (1 Byte):  Size (in bytes) of network level addresses. In the case of IP this field must be worth 4.
  • Opcode (2 Bytes):  ARP operation indicator. If the ARP package is a request ( Request ) this field is worth 0x0001 while if it is a response ( Reply ) this field is worth 0x0002.
  • Eth Sender (6 Bytes):  Ethernet address of the ARP packet sender.
  • IP Sender (4 Bytes):  IP address of the ARP packet sender.
  • Target Eth (6 bytes):  Ethernet address of the ARP packet receiver. If the Opcode of the packet is 1 this value will be the null address (6 bytes to 0) since it is not known what the Ethernet address is.
  • Target IP (4 Bytes):  IP address of the ARP packet receiver.


Exercises

The ultimate goal of this practice is to implement a program that makes ARP resolutions. To do this, it will read an IP address by keyboard, make an ARP request and if it receives a response it will show the associated Ethernet address. In order to perform these actions it will be necessary to implement Ethernet and ARP. In this sense, it is proposed to start from the code provided, complete and expand the code delivered in the ethernet.py and arp.py files. The following describes the functions that must be implemented in both files:


ethertnet.py:

startEthernetLevel (interface):

Description:

  • This function is called a network interface and initializes the Ethernet level. This function must perform at least the following tasks:
    • Check if the Ethernet level was already initialized (using a global variable). If it was already initialized return -1.
    • Obtain and store the MAC address associated with the specified interface in a global variable
    • Open the specified interface in promiscuous mode using the rc1-pcap library
    • Start a receive thread (rxThread) that calls the pcap_loop function.
    • If everything is correct, mark the global level variable set to True
Arguments:

  • interface:  text string with the interface name on which to initialize the Ethernet level
Return:

  • 0 if everything is correct
  • -1 otherwise


stopEthernetLevel ():

Description:

  • This function will stop and release all the necessary resources associated with the Ethernet level. This function must perform at least the following tasks:
    • Stop the packet receiving thread 
    • Close the interface (pcap handle)
    • Mark the global level variable initialized to False
Arguments:

  • None
Return:

  • 0 if everything is correct
  • -1 otherwise

registerCallback (callback_func, ethertype):

Description:

  • This function will receive the name of a function and its associated ethertype value and will add this association to the table (dictionary) of higher level protocols. This mechanism allows us to know which higher level function we should call when receiving a frame of a certain type. For example, we can register a function called process_IP_datagram associated with the Ethertype 0x0800 and another function called process_arp_packet associated with the Ethertype 0x0806. 
Arguments:

  • callback_fun: callback  function to be executed when the specified Ethertype is received. The function passed as an argument must have the following prototype:
    • function (us, header, data, srcMac)
    • Where:
      • us: are the user data passed by pcap_loop (in our case this value will always be None)
      • header: pcap_pkthdr structure that contains the len, caplen and ts fields.
      • data: payload of the Ethernet frame. That is, the Ethernet header is NEVER passed up.
      • srcMac: MAC address that has sent the current frame.
    • The function will not return anything. If a frame is to be discarded, it is enough to make a return without value and it will stop processing.
  • ethertype:  Ethernetype value for which you want to register a callback function.
Return:

  • None


sendEthernetFrame (data, len, etherType, dstMac):

Description:

  • This function will build an Ethernet frame with the received data and send it through the network interface. This function must perform at least the following tasks:
    • Build the Ethernet frame to send (including header + payload). Own fields (for example the source Ethernet address) must be obtained from the variables that have been initialized in startEthernetLevel
    • Check the Ethernet limits. If the plot is very small, it must be filled in with 0s while if it is very large, an error must be returned.
    • Call pcap_inject to send the frame and check the return of that call. In case there is error notify
Arguments:

  • data: useful data or payload to encapsulate within the Ethernet frame
  • len: length of useful data expressed in bytes
  • etherType: Ethernet type value to be included in the frame
  • dstMac: Destination MAC address to be included in the frame to be sent
Return:

  • 0 if everything is correct
  • -1 otherwise



process_Ethernet_frame (us, header, data):

Description:

  • This function will be executed every time an Ethernet frame arrives. This function must perform at least the following tasks:
    • Extract the destination, source and ethertype Ethernet address fields
    • Check if the destination address is your own or broadcast address. In case the plot is not broadcast or it is not for our interface, we will discard it (making a return).
    • Check if there is a higher level callback function associated with the Ethertype of the frame:
      • If it exists, call the higher level function with the corresponding parameters:
        • us (user data)
        • header (pcap_pktheader header)
        • payload (frame data excluding the Ethernet header)
        • source Ethernet address
      • In case there is no return
Arguments:

  • us:  User data passed from pcap_loop (in our case this will be None)
  • header:  pcap_pkthdr structure that contains the len, caplen and ts fields.
  • data:  bytearray with the content of the Ethernet frame
Return:

  • None


arp.py:

initARP (interface):

Description:

  • This function will build initialize the ARP level. This function must perform at least the following tasks:
    • Register the callback function process_arp_frame (described below) with the Ethertype 0x0806
    • Obtain and store the MAC and IP address associated with the specified interface
    • Make a free ARP request and check if your own IP is already assigned. If positive, error must be returned.
    • Mark the ARP level variable initialized to True
Arguments:

  • interface:  string with the name of the interface where the ARP level should be initialized (for example h1-eth0)
Return:
  • 0 if everything is correct
  • -1 otherwise


ARPResolution (ip):

Description:

  • This function attempts to perform an ARP resolution for a given IP and returns the MAC address associated with that IP or None in case it has not received a response. This function must perform at least the following tasks:
    • Check if the requested IP exists in the cache:
      • If it is in cache return the information from the cache
      • If it is not in the cache:
        • Build an ARP request by calling the createARPRequest function (description below)
        • Send that request
        • Check if response has been received or not:
          • If no reply has been received, forward the request up to 3 times. If no response is received return None
          • If reply has been received return the MAC address
  • This function will need to communicate with the reception function (to check for a response and the response itself) using 3 global variables:
    • awaitingResponse: indicates if True is waiting for response. If it is False it means that an answer has been received
    • requestedIP: contains the IP for which you are asking
    • resolvedMAC: contains the resolved MAC address (in case awaitingResponse) is False.
  • As these global variables are read and written concurrently they must be protected with a Lock
Arguments:

  • interface:  ip to solve
Return:
  • None  if there is no answer
  • MAC  associated with the IP in case there is a response



process_arp_frame (us, header, data, srcMac):

Description:

  • This function processes ARP frames. It will be executed for each Ethenet frame received with Ethertype 0x0806 (if it has been registered in initARP). This function must perform at least the following tasks:
    • Extract the common ARP header (first 6 bytes) and verify that it is correct
    • Extract the opcode field
    • If opcode is 0x0001 (Request) call processARPRequest (see description below)
    • If opcode is 0x0002 (Reply) call processARPReply (see description below)
    • If it is another opcode return from the function
    • In case there is no return
Arguments:

  • us: User data passed from the pcap_loop call. In our case it will be None
  • header: pcap_pktheader header
  • data: byte array with the content of the ARP frame
  • srcMac: MAC source of the Ethernet frame received
Return:

  • None


processARPRequest (data, MAC):

Description:

  • This function processes an ARP request. This function must perform at least the following tasks:
    • Extract the source MAC contained in the ARP request
    • If the source MAC of the ARP frame is not the same as the one received from the Ethernet level, return
    • Extract the source IP contained in the ARP request


Related Questions in computer science category