This is a low-level network debugging utility that utilizes raw packet i/o to construct and deconstruct tcp, udp, ipv4, arp, and icmp packets over ethernet.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 #include "mbed.h"
00002 #include "string.h"
00003 
00004 #include "util/types.h"
00005 #include "util/log.h"
00006 #include "util/util.h"
00007 #include "sniffer.h"
00008 #include "scanner.h"
00009 
00010 #include <string>
00011 #include <queue>
00012 
00013 /**
00014   \file main.cpp
00015   \brief This is the primary NetTool demo file.
00016   
00017   This file is the brains of the NetTool, utilizing the networking code
00018   found in other files to do some basic network diagnostic stuff.
00019   Note that for the nettool to connect to a computer, the computer has
00020   to already have an IP configured on the interface, which usually
00021   requires that the interface or connection be manually assigned an IP
00022   address.
00023 */
00024 
00025 // The main logger (global scope)
00026 Sniffer sniffer;
00027 Log main_log;
00028 bool main_running = true;
00029 
00030 Ethernet_MAC BROADCAST_MAC = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
00031 Ethernet_MAC your_mac;
00032 
00033 IP_Address my_ip = {0x00, 0x00, 0x00, 0x00};
00034 IP_Address your_ip;
00035 
00036 bool portscan_started = false;
00037 bool ip_determined = false;
00038 
00039 LocalFileSystem local("local");
00040 queue<string> commands;
00041 
00042 inline void loadCommands()
00043 {
00044   FILE *fp = fopen("/local/ntcmd.txt", "r");
00045   if (fp)
00046   {
00047     char buf[256];
00048     while (NULL != fgets(buf, 256, fp))
00049     {
00050       if (buf[0] == '#') continue;
00051       else if (strlen(buf) == 0) continue;
00052       else if (!strncmp(buf, "ping", 4)) commands.push("ping");
00053       else if (!strncmp(buf, "portscan", 8)) commands.push("portscan");
00054       else if (!strncmp(buf, "identify", 8)) commands.push("identify");
00055       else main_log.printf("Unknown command: %s", buf);
00056     }
00057   }
00058   else
00059   {
00060     // Write the ntcmd file with some help
00061     main_log.printf("No net tool command file found!");
00062     fp = fopen("/local/ntcmd.txt", "w");
00063     fprintf(fp, "# Net Tool Command File Help:\n");
00064     fprintf(fp, "# 1. Comments start with the pound sign\n");
00065     fprintf(fp, "# 2. Commands are on a line by themselves\n");
00066     fprintf(fp, "# Known commands:\n");
00067     fprintf(fp, "# 1. ping - Send a ping to the host computer every 30 seconds and write results to PING.TXT\n");
00068     fprintf(fp, "# 2. portscan - Scan the host computer and write open TCP ports to PORTSCAN.TXT\n");
00069     fprintf(fp, "# 3. identify - Write host computer information to IDENTITY.TXT\n");
00070   }
00071   fclose(fp);
00072 }
00073 
00074 Ticker ping_timer;
00075 void ping()
00076 {
00077 #define PING_BUFEFERSIZE (sizeof(IP_PacketHeader) + sizeof(ICMP_Packet))
00078     u8 buffer[PING_BUFEFERSIZE];
00079     IP_PacketHeader *ip_packet = (IP_PacketHeader*)buffer;
00080     ICMP_Packet *ping_packet = (ICMP_Packet*)ip_packet->data;
00081     
00082     memset(buffer, '\0', PING_BUFEFERSIZE);
00083     
00084     *ip_packet = (IP_PacketHeader){0x04, 5, 0, sizeof(IP_PacketHeader)+sizeof(ICMP_Packet), 0, 0, 0, 0, 0, 32, IPPROTO_ICMP, 0x00, my_ip, your_ip};
00085     *ping_packet = (ICMP_Packet){ICMP_ECHO_REQUEST, 0x00, 0x00, 0x00, 0x00};
00086     
00087     fix_endian_icmp(ping_packet);
00088     fix_endian_ip(ip_packet);
00089     ip_packet->header_checksum = checksum(ip_packet, sizeof(IP_PacketHeader), &ip_packet->header_checksum, 2);
00090     ping_packet->checksum = checksum(ping_packet, sizeof(ICMP_Packet), &ping_packet->checksum, 2);
00091     
00092     
00093     FILE *fp = fopen("/local/ping.txt", "w");
00094     fprintf(fp, "PING sent...\n");
00095     fclose(fp);
00096     
00097     sniffer.inject(your_mac, ETHERTYPE_IPV4, buffer, PING_BUFEFERSIZE);
00098 }
00099 
00100 void identify()
00101 {
00102     FILE *fp = fopen("/local/identity.txt", "w");
00103     fprintf(fp, "Connected host identity:\n");
00104     
00105     u8 *octets = your_mac.octet;
00106     fprintf(fp, "  MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", octets[0],octets[1],octets[2],octets[3],octets[4],octets[5]);
00107     
00108     octets = your_ip.octet;
00109     fprintf(fp, "  IP  Address: %d.%d.%d.%d\n", octets[0],octets[1],octets[2],octets[3]);
00110     
00111     fclose(fp);
00112 }
00113 
00114 int main() {
00115     // Enable logging via USB
00116     main_log.enable(LOG_USB);
00117     main_log.printf("");
00118     
00119     // Startup sequence
00120     main_log.printf("Booting...");
00121     Scanner scanner(&sniffer); // Hooks into TCP handler
00122     
00123     main_log.printf("Loading commands...");
00124     loadCommands();
00125 
00126     main_log.printf("Starting...");
00127     while(main_running) {
00128         // Get the next frame
00129         sniffer.next();
00130         
00131         // Handle ICMP packet
00132         if (sniffer.icmp_packet)
00133         {
00134             // If the packet is an ICMP ECHO (Ping) request
00135             if (sniffer.icmp_packet->type == ICMP_ECHO_REQUEST)
00136             {   
00137                 // Build the ICMP packet
00138                 sniffer.icmp_packet->type = ICMP_ECHO_REPLY;
00139                 
00140                 // Build the IP packet
00141                 sniffer.ip_packet->destination = sniffer.ip_packet->source;
00142                 sniffer.ip_packet->source = my_ip;
00143                 
00144                 // Inject the packet
00145                 fix_endian_icmp(sniffer.icmp_packet);
00146                 fix_endian_ip(sniffer.ip_packet);
00147                 sniffer.icmp_packet->checksum = checksum(sniffer.icmp_packet, sizeof(ICMP_Packet) + sniffer.data_bytes, &sniffer.icmp_packet->checksum, 2);
00148                 sniffer.ip_packet->header_checksum = checksum(sniffer.ip_packet, sizeof(IP_PacketHeader), &sniffer.ip_packet->header_checksum, 2);
00149                 sniffer.inject(sniffer.frame_header->source, ETHERTYPE_IPV4, sniffer.ip_packet, sizeof(IP_PacketHeader) + sizeof(ICMP_Packet) + sniffer.data_bytes);
00150             }
00151             else if (sniffer.icmp_packet->type == ICMP_ECHO_REPLY)
00152             {
00153                 FILE *fp = fopen("/local/ping.txt", "a");
00154                 fprintf(fp, "PING reply received\n");
00155                 fclose(fp);
00156             }
00157         }
00158         // Handle ARP packet
00159         else if (sniffer.arp_packet)
00160         {
00161             // These conditions can be optimized a lot
00162             // Check for an ARP request
00163             if (is_nonzero_mem(sniffer.arp_packet->sender_hardware_address, 6) &&
00164                 is_nonzero_mem(sniffer.arp_packet->sender_protocol_address, 4) &&
00165                 is_nonzero_mem(my_ip.octet, 4) &&
00166                 is_equal_mem(sniffer.arp_packet->target_protocol_address, my_ip.octet, 4) &&
00167                 sniffer.arp_packet->operation == 1)
00168             {
00169                 //main_log.printf("ARP Requested:");
00170                 //main_log.printf("  Responding with IP - %03d.%03d.%03d.%03d", my_ip.octet[0],my_ip.octet[1],my_ip.octet[2],my_ip.octet[3]);
00171                 Ethernet_MAC *targmac = (Ethernet_MAC*)sniffer.arp_packet->target_hardware_address;
00172                 IP_Address   *targip  = (IP_Address*)sniffer.arp_packet->target_protocol_address;
00173                 Ethernet_MAC *srcmac  = (Ethernet_MAC*)sniffer.arp_packet->sender_hardware_address;
00174                 IP_Address   *srcip   = (IP_Address*)sniffer.arp_packet->sender_protocol_address;
00175                 
00176                 // Set the ARP options
00177                 *targmac = *srcmac;
00178                 *srcmac  = sniffer.mac;
00179                 *targip  = *srcip;
00180                 *srcip   = my_ip; 
00181                 sniffer.arp_packet->operation = 2;
00182                 
00183                 fix_endian_arp(sniffer.arp_packet);
00184                 sniffer.inject(BROADCAST_MAC, ETHERTYPE_ARP, sniffer.arp_packet, sizeof(ARP_Packet));
00185                 
00186                 if (!portscan_started) {
00187                     portscan_started = true;
00188                 }
00189             }
00190             // Check for an ARP announce
00191             if (is_nonzero_mem(sniffer.arp_packet->sender_hardware_address, 6) &&
00192                 is_zero_mem   (sniffer.arp_packet->sender_protocol_address, 4) &&
00193                 is_zero_mem   (sniffer.arp_packet->target_hardware_address, 6) &&
00194                 sniffer.arp_packet->operation == 1)
00195             {
00196                 if (ip_determined) continue;
00197                 ip_determined = true;
00198                 
00199                 //main_log.printf("ARP Announce Received:");
00200                 my_ip = your_ip = *(IP_Address*)sniffer.arp_packet->target_protocol_address;
00201                 main_log.printf("Host IP: %03d.%03d.%03d.%03d", my_ip.octet[0],my_ip.octet[1],my_ip.octet[2],my_ip.octet[3]);
00202                 do { my_ip.octet[3]++; } while (!my_ip.octet[3]);
00203                 main_log.printf("Tool IP: %03d.%03d.%03d.%03d", my_ip.octet[0],my_ip.octet[1],my_ip.octet[2],my_ip.octet[3]);
00204                 
00205                 Ethernet_MAC *targmac = (Ethernet_MAC*)sniffer.arp_packet->target_hardware_address;
00206                 IP_Address   *targip  = (IP_Address*)sniffer.arp_packet->target_protocol_address;
00207                 Ethernet_MAC *srcmac  = (Ethernet_MAC*)sniffer.arp_packet->sender_hardware_address;
00208                 IP_Address   *srcip   = (IP_Address*)sniffer.arp_packet->sender_protocol_address;
00209                 
00210                 your_mac = *srcmac;
00211                 
00212                 // Set the ARP options
00213                 *targmac = sniffer.mac;
00214                 *srcmac  = sniffer.mac;
00215                 *targip  = my_ip;
00216                 *srcip   = my_ip; 
00217                 sniffer.arp_packet->operation = 2;
00218                 
00219                 fix_endian_arp(sniffer.arp_packet);
00220                 sniffer.inject(BROADCAST_MAC, ETHERTYPE_ARP, sniffer.arp_packet, sizeof(ARP_Packet));
00221                 
00222                 while (!commands.empty())
00223                 {
00224                     string command = commands.front();
00225                     main_log.printf("NetTool> %s", command.c_str());
00226                     if (command == "ping")
00227                         ping_timer.attach(&ping, 30);
00228                     else if (command == "portscan")
00229                         scanner.start(sniffer.mac, your_mac, my_ip, your_ip);
00230                     else if (command == "identify")
00231                         identify();
00232                     commands.pop();
00233                 }
00234             }
00235         }
00236         else if (sniffer.tcp_packet)
00237         {
00238         }
00239     }
00240     
00241     // This shouldn't really happen...
00242     main_log.printf("Terminating...");
00243     return 0;
00244 }