Classes - Simple Sniffer

header.png

Object Oriented Programming (OOP) is a programming paradigm that promotes the design of programs that solve problems through the interaction of objects. C++ is one of the programming languages that promotes object oriented programming, allowing programmers to create their own classes from scratch or derive them from other existing classes. Other languages that promote OOP are Java, Python, JavaScript and PHP.

In today's laboratory experience, you will practice the definition of classes and the implementation of methods by completing a program that implements a simplified network sniffer. Every data that your computer receives or sends to/from through the network is formatted as a network packet. A network sniffer is an application commonly used by network specialists and hackers to inspect packets. It listens to the signals going through your computer's network interface and presents the captured data in a structured format. Since each packet contains various pieces of data, such as the address of the source and destination computers, it is common in programming to represent packets as objects. In the exercises of this laboratory you will create classes for network packets at the Ethernet and Internet Protocol levels. Once the classes are correctly implemented, you will be able to run the network sniffer application and inspect out the gory details of what goes through your network interface everytime you send/receive data.

Objectives

  1. Practice the implementation and declaration of classes in C++.
  2. Implement methods in a class.

Pre-Lab:

Before you get to the laboratory you should have:

  1. Reviewed the implementation and declaration of C++ classes
  2. Studied the concepts and instructions for this laboratory session.
  3. Taken the Pre-Lab quiz, available in Moodle


Classes and Objects in C++

An object is an entity that contains data and procedures to manipulate them. Similar to how each variable has a type of data associated to it, each object has a class associated to it, which describes the properties of the the objects: its data (attributes), and the procedures that can be used to manipulate its data (methods).

It is not necessary to know all of the details about the methods of the object to define and use an object, but you must know how to create it and how to interact with it. The necessary information is available in the class's documentation. Before creating objects of any class, we should familiarize ourselves with its documentation. The documentation indicates, among other things, what entity is trying to be represented in the class, and its interface or methods available to manipulate the objects of the class.

To see an example of a class, take a look at the documentation of the Bird class which can be found in this link.

Classes

A class is a description of the data and processes of an object. The class declaration establishes the attributes that each of the objects of the class will have, and the methods that it can invoke.

The attributes and methods of a class can have one the following levels of access: private, protected and public. An object's public data members can be read or modified by any function that has access to the object (including external functions). An object's private data members can only be read or modified through the object's member functions . Unless specified otherwise, the attributes and methods defined in a class will be private. Protected members allow read/write access from member functions and those of inherited classes.

The following is the skeleton of the declaration of a class:


  class ClassName
   {
    // Declarations

    private:
      // Declaration of variables or attributes
      // and prototype member functions
      // that are private for this class

      type privateVar
      type nameOfPrivateMemFunc(type of the parameters);

    public:
      // Declarations of attributes
      // and prototypes of method functions
      // that are public for the entire program

      type publicVar;
      type nameOfPublicMemFunc(type of the parameters);
   };


Communication Among Computers

Computers communicate with each other through the Internet Protocol (IP). When a computer sends information to another computer, the information is sent via Internet packets that contain the source address, which is the Internet address of the computer sending the information, and the destination address, which is the Internet address of the computer that receives the message. The Internet addresses are used to guide the information from one computer to another, but once the packet arrives to its destination, who is supposed to receive the information? Which application must receive the information?

The Internet packets must also specify the application that is sending the information and the application that must receive it. We can think of the Internet addresses like home postal mail addresses, and that the applications that send and receive the information are the persons that send and receive postal letters. To send a letter via postal mail, the recipient of the letter must be specified. This corresponds to the application that receives the information. To identify the source and destination application, the Internet protocol uses what is known as port numbers. This way, looking at the packet information, the source and destination addresses and ports can be identified.

For instance, when your lab computer communicates with the Moodle server, the packets that carry the information from your computer to the web server contain the source address, which is the address of the lab computer, and the destination address which is the Moodle server. The source port is the port of your web browser and the destination port is the port of the Moodle web server.

Internet addresses occupy 4 bytes (32 bits), and usually are presented to users as strings of 4 decimal values. Each decimal value between 0 and 255 is the decimal representation of one of the 4 bytes: "(0-255).(0-255).(0-255).(0-255)". Some examples of IP addresses are: 10.0.1.10, 192.168.10.11, 136.145.54.10.

Port numbers are composed of 2 bytes or 16 bits and range from 0-65535. There are ports numbers assigned to known application services such as number 22 for ssh, 23 for telnet, 25 for smtp, 80 for http, and so on.

To complicate things a little bit, each computer network card has a unique identifier that is used for the communication between your computer and the network device that routes the network traffic from the Internet and local network to your computer and vice-versa (Ethernet protocol). This unique identifier is known as the Hardware address (a.k.a Multiple Access Control (MAC) address), is represented using 6 bytes (48 bits), and is presented to the users as strings of 6 hexadecimal values (each pair of hexadecimal digits corresponds to 1 byte). Each hex value is the hex representation of the 6 bytes: "(00-ff):(00-ff):(00-ff):(00-ff):(00-ff):(00-ff)". Some examples of MAC addresses are: e0:f8:47:01:e9:90 and 70:ad:60:ff:fe:dd:79:d8.


Simple Packet Sniffer

A packet sniffer (also known as packet analyzer - protocol analyzer - or network analyzer) is a computer program that can intercept and log traffic passing over a digital network, or network device. As data flows across the network, the sniffer captures each packet and, if needed, decodes the packet's raw data[1].

Each packet captured by a sniffer has a structure similar to the illustration in Figure 1.


figure1.png

Figure 1. Structure of each Ethernet packet captured by a sniffer.


Inside the structure shown in Figure 1 is found:

  1. Destination MAC Address and Source Mac Address: are the source and destination MAC addresses
  2. Ether type: is used to indicate the type of protocol used in the payload. One of the possible payloads is an IP packet.
  3. Payload: contains an IP packet (in reality it can contain other protocols, but for this laboratory experience we will asume that it contains only IP).

Inside the payload, the IP packet contains various field, among them:

  1. The source and destination IP addresses
  2. The source and destination port numbers
  3. The IP packet payload. Inside this payload the data that wants to be communicated is contained.

In this laboratory experience, you will complete a simple packet sniffer that captures all the IP packets that flow through your laboratory computer, and some additional information of the packets. Additionally, it detects the non encrypted requests of images in the web, and displays the images in the GUI.

For the purposes of this lab, we will think of IP packets as being a specialization of Ethernet packets. As such, it is a good strategy to implement the IP packet as class that is derived from the Ethernet packet class through inheritance. Thus, the IP packet class will have all the data members and methods of the Ethernet class (for example, source and destination MAC addresses) plus additional data members and methods that apply specifically to IP Packets (for example source and destination ports).



A lazy programmer has given you the following class declaration:
Which of the following is most likely a getter?
myClass() int xx() void zz(int someValue) a The correct answer is xx. Getter functions read a value from one or more data members. Thus the protoype of a getter is a non-void function without parameters. About the rest of the options:
myClass is a constructor (it has the same name as the class)
void zz(int someValue) is most probably a seter since it is a void function that receives a parameter of the type of one of the class' data members
a is a data member.



Laboratory Session:

The application that you will complete today allows the users to analyze network traffic and monitor the images that are being tranfered through the net.

Figure 2 shows an image of the application interface. Each row in the table is the information of each captured packet. The text box under the table presents an ASCII summary of a selected packet from the table. The list in the right presents the images that have been captured by the sniffer.


Figure 2. The user interface of the Simple Packet Sniffer application.


To create a packet sniffer you can use the pcap library that provides an interface to access the data passing across your network card. This library contains a function that returns a raw stream of bytes of each packet captured.

The task of the sniffer programmer to decode the raw stream into human readable information. Fortunately this is not your task, but you can learn how to do it, if you want, by reading the source code of this laboratory. Your task is to follow the exercises below so you provide the packet sniffer with the needed objects (classes) to process the packets.

Exercise 1 - Familiarize Yourself with the Application

Instructions

  1. Load the project SimpleSniffer into QtCreator. There are two ways to do this:

    • Using the virtual machine, you need to run QtCreator with administrator (root) privileges.: sudo qtcreator /home/eip/labs/classes-simplesniffer/SimpleSniffer.pro
    • Downloading the project�s folder from Bitbucket: Use a terminal and write the command git clone http:/bitbucket.org/eip-uprrp/classes-simplesniffer to download the folder classes-simplesniffer from Bitbucket. In this directory, you need to run QtCreator with administrator (root) privileges: sudo qtcreator ./SimpleSniffer.pro
  2. Configure the project. In this laboratory experience you will be working with the files ethernet_hdr.h, ethernet_packet.h, ethernet_packet.cpp, ip_packet.h and ip_packet.cpp.

Exercise 2 - Complete the Class ethernet_packet

  1. Study the file ethernet_hdr.h. This file contains the definition of the data structure that represents an Ethernet header.:

    #define ETHER_ADDR_LEN 6
    
    struct sniff_ethernet {
        u_char  ether_dhost[ETHER_ADDR_LEN];    /* destination host address */
        u_char  ether_shost[ETHER_ADDR_LEN];    /* source host address */
        u_short ether_type;                     /* IP? ARP? RARP? etc */
    };

    The Ethernet header above is used to decode the ethernet part of the raw data in each packet. It is composed of the source MAC address (ether_shost, 6 bytes), the destination MAC address (ether_dhost, 6 bytes), and the type of Ethernet packet (ether_type, 2 bytes), which is used to determine if the packet is an IP packet.

    As you know, it is not a good idea to show this information format to a regular user. Your first task is to define the functions of the C++ class that defines the functions that translate the MAC address information into human readable strings.

  2. The following code is the definition of the class ethernet_packet, that can be found in file ethernet_packet.h:

     class ethernet_packet
     {
        sniff_ethernet ethernet ;
    
        // Returns a 6 bytes MAC address in string representation.
        string mac2string(u_char []) ;
    
     public:
        ethernet_packet();  // Default constructor
    
        // Set the ethernet variable member ether_dhost to the values
        // received in the array
        void setEtherDHost(u_char []) ;
    
        // Same as above but to the ether_shost
        void setEtherSHost(u_char []) ;
    
        // Set the ethernet type to the value received.
        void setEtherType(u_short) ;
    
        // returns the string representation of the ethernet addresses
        string getEtherDHost() ;
        string getEtherSHost() ;
    
        // Return the ethernet type
        u_short getEtherType() ;
     };

    Note that each object of the class ethernet_packet only has one attribute: a structure of type sniff_ethernet named ethernet

  3. The rest are methods that act as interface to the attribute:

    • void setEtherDHost(u_char []): is a setter to the field ether_dhost of the attribute ethernet
    • void setEtherSHost(u_char []): is a setter to the field ether_shost of the attribute ethernet
    • void setEtherType(u_short): is a setter for the field ether_type of the attribute ethernet
    • getEtherDHost() and getEtherSHost() are getters that return the values of ether_dhost and ether_shost in a human readable format, i.e. 6 pairs of hexadecimal digits (for example, e0:f8:47:01:e9:90).
    • getEtherType() is a getter that returns the value of ether_type as unsigned char.
    • the private method string mac2string(u_char []) receives an array of six unsigned characters and returns the corresponding string to its hexadecimal representation. For example, if it receives { 0x8A, 0x11, 0xAB, 0xFF, 0x12, 0x34} it must return the string "8A:11:AB:FF:12:34".
  4. Your task in this exercise is to implement the seven functions listed above in the file ethetnet_packet.cpp. The headers of some of the functions are provided in the file.

Exercise 3 - Build the Header of the Class ip_packet

  1. Study the definitions of the functions of the class ip_packet found in file ip_packet.cpp

  2. Your task is to create the declaration of the class ip_packet in the file ip_packet.cpp. The attributes of the class ip_packet must be:

    • two objects of the class string to store the source and destination IP addresses
    • one variable of one byte (char) variable to store the IP protocol
    • two variables unsigned short to store the source and destination port
    • one object of the class string to store the packet payload.

      In the declaration of the class ip_packet you must specify that it is a derived class (inherits) of the class ethernet_packet.



Deliverables

  1. Use "Deliverables" in Moodle to upload the file ethernet_packet.cpp and ip_packet.h that you defined. Remember to use good programming techniques, include the names of the programmers involved, and document your program.


References

[1] http://en.wikipedia.org/wiki/Packet_analyzer

results matching ""

    No results matching ""