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

Revision:
0:d494b853ce97
Child:
6:66c4cd9073aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 12 05:32:59 2010 +0000
@@ -0,0 +1,232 @@
+#include "mbed.h"
+#include "string.h"
+
+#include "util/types.h"
+#include "util/log.h"
+#include "util/util.h"
+#include "sniffer.h"
+#include "scanner.h"
+
+#include <string>
+#include <queue>
+
+// The main logger (global scope)
+Sniffer sniffer;
+Log main_log;
+bool main_running = true;
+
+Ethernet_MAC BROADCAST_MAC = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+Ethernet_MAC your_mac;
+
+IP_Address my_ip = {0x00, 0x00, 0x00, 0x00};
+IP_Address your_ip;
+
+bool portscan_started = false;
+bool ip_determined = false;
+
+LocalFileSystem local("local");
+queue<string> commands;
+
+inline void loadCommands()
+{
+  FILE *fp = fopen("/local/ntcmd.txt", "r");
+  if (fp)
+  {
+    char buf[256];
+    while (NULL != fgets(buf, 256, fp))
+    {
+      if (buf[0] == '#') continue;
+      else if (strlen(buf) == 0) continue;
+      else if (!strncmp(buf, "ping", 4)) commands.push("ping");
+      else if (!strncmp(buf, "portscan", 8)) commands.push("portscan");
+      else if (!strncmp(buf, "identify", 8)) commands.push("identify");
+      else main_log.printf("Unknown command: %s", buf);
+    }
+  }
+  else
+  {
+    // Write the ntcmd file with some help
+    main_log.printf("No net tool command file found!");
+    fp = fopen("/local/ntcmd.txt", "w");
+    fprintf(fp, "# Net Tool Command File Help:\n");
+    fprintf(fp, "# 1. Comments start with the pound sign\n");
+    fprintf(fp, "# 2. Commands are on a line by themselves\n");
+    fprintf(fp, "# Known commands:\n");
+    fprintf(fp, "# 1. ping - Send a ping to the host computer every 30 seconds and write results to PING.TXT\n");
+    fprintf(fp, "# 2. portscan - Scan the host computer and write open TCP ports to PORTSCAN.TXT\n");
+    fprintf(fp, "# 3. identify - Write host computer information to IDENTITY.TXT\n");
+  }
+  fclose(fp);
+}
+
+Ticker ping_timer;
+void ping()
+{
+#define PING_BUFEFERSIZE (sizeof(IP_PacketHeader) + sizeof(ICMP_Packet))
+    u8 buffer[PING_BUFEFERSIZE];
+    IP_PacketHeader *ip_packet = (IP_PacketHeader*)buffer;
+    ICMP_Packet *ping_packet = (ICMP_Packet*)ip_packet->data;
+    
+    memset(buffer, '\0', PING_BUFEFERSIZE);
+    
+    *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};
+    *ping_packet = (ICMP_Packet){ICMP_ECHO_REQUEST, 0x00, 0x00, 0x00, 0x00};
+    
+    fix_endian_icmp(ping_packet);
+    fix_endian_ip(ip_packet);
+    ip_packet->header_checksum = checksum(ip_packet, sizeof(IP_PacketHeader), &ip_packet->header_checksum, 2);
+    ping_packet->checksum = checksum(ping_packet, sizeof(ICMP_Packet), &ping_packet->checksum, 2);
+    
+    
+    FILE *fp = fopen("/local/ping.txt", "w");
+    fprintf(fp, "PING sent...\n");
+    fclose(fp);
+    
+    sniffer.inject(your_mac, ETHERTYPE_IPV4, buffer, PING_BUFEFERSIZE);
+}
+
+void identify()
+{
+    FILE *fp = fopen("/local/identity.txt", "w");
+    fprintf(fp, "Connected host identity:\n");
+    
+    u8 *octets = your_mac.octet;
+    fprintf(fp, "  MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", octets[0],octets[1],octets[2],octets[3],octets[4],octets[5]);
+    
+    octets = your_ip.octet;
+    fprintf(fp, "  IP  Address: %d.%d.%d.%d\n", octets[0],octets[1],octets[2],octets[3]);
+    
+    fclose(fp);
+}
+
+int main() {
+    // Enable logging via USB
+    main_log.enable(LOG_USB);
+    main_log.printf("");
+    
+    // Startup sequence
+    main_log.printf("Booting...");
+    Scanner scanner(&sniffer); // Hooks into TCP handler
+    
+    main_log.printf("Loading commands...");
+    loadCommands();
+
+    main_log.printf("Starting...");
+    while(main_running) {
+        // Get the next frame
+        sniffer.next();
+        
+        // Handle ICMP packet
+        if (sniffer.icmp_packet)
+        {
+            // If the packet is an ICMP ECHO (Ping) request
+            if (sniffer.icmp_packet->type == ICMP_ECHO_REQUEST)
+            {   
+                // Build the ICMP packet
+                sniffer.icmp_packet->type = ICMP_ECHO_REPLY;
+                
+                // Build the IP packet
+                sniffer.ip_packet->destination = sniffer.ip_packet->source;
+                sniffer.ip_packet->source = my_ip;
+                
+                // Inject the packet
+                fix_endian_icmp(sniffer.icmp_packet);
+                fix_endian_ip(sniffer.ip_packet);
+                sniffer.icmp_packet->checksum = checksum(sniffer.icmp_packet, sizeof(ICMP_Packet) + sniffer.data_bytes, &sniffer.icmp_packet->checksum, 2);
+                sniffer.ip_packet->header_checksum = checksum(sniffer.ip_packet, sizeof(IP_PacketHeader), &sniffer.ip_packet->header_checksum, 2);
+                sniffer.inject(sniffer.frame_header->source, ETHERTYPE_IPV4, sniffer.ip_packet, sizeof(IP_PacketHeader) + sizeof(ICMP_Packet) + sniffer.data_bytes);
+            }
+            else if (sniffer.icmp_packet->type == ICMP_ECHO_REPLY)
+            {
+                FILE *fp = fopen("/local/ping.txt", "a");
+                fprintf(fp, "PING reply received\n");
+                fclose(fp);
+            }
+        }
+        // Handle ARP packet
+        else if (sniffer.arp_packet)
+        {
+            // These conditions can be optimized a lot
+            // Check for an ARP request
+            if (is_nonzero_mem(sniffer.arp_packet->sender_hardware_address, 6) &&
+                is_nonzero_mem(sniffer.arp_packet->sender_protocol_address, 4) &&
+                is_nonzero_mem(my_ip.octet, 4) &&
+                is_equal_mem(sniffer.arp_packet->target_protocol_address, my_ip.octet, 4) &&
+                sniffer.arp_packet->operation == 1)
+            {
+                //main_log.printf("ARP Requested:");
+                //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]);
+                Ethernet_MAC *targmac = (Ethernet_MAC*)sniffer.arp_packet->target_hardware_address;
+                IP_Address   *targip  = (IP_Address*)sniffer.arp_packet->target_protocol_address;
+                Ethernet_MAC *srcmac  = (Ethernet_MAC*)sniffer.arp_packet->sender_hardware_address;
+                IP_Address   *srcip   = (IP_Address*)sniffer.arp_packet->sender_protocol_address;
+                
+                // Set the ARP options
+                *targmac = *srcmac;
+                *srcmac  = sniffer.mac;
+                *targip  = *srcip;
+                *srcip   = my_ip; 
+                sniffer.arp_packet->operation = 2;
+                
+                fix_endian_arp(sniffer.arp_packet);
+                sniffer.inject(BROADCAST_MAC, ETHERTYPE_ARP, sniffer.arp_packet, sizeof(ARP_Packet));
+                
+                if (!portscan_started) {
+                    portscan_started = true;
+                }
+            }
+            // Check for an ARP announce
+            if (is_nonzero_mem(sniffer.arp_packet->sender_hardware_address, 6) &&
+                is_zero_mem   (sniffer.arp_packet->sender_protocol_address, 4) &&
+                is_zero_mem   (sniffer.arp_packet->target_hardware_address, 6) &&
+                sniffer.arp_packet->operation == 1)
+            {
+                if (ip_determined) continue;
+                ip_determined = true;
+                
+                //main_log.printf("ARP Announce Received:");
+                my_ip = your_ip = *(IP_Address*)sniffer.arp_packet->target_protocol_address;
+                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]);
+                do { my_ip.octet[3]++; } while (!my_ip.octet[3]);
+                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]);
+                
+                Ethernet_MAC *targmac = (Ethernet_MAC*)sniffer.arp_packet->target_hardware_address;
+                IP_Address   *targip  = (IP_Address*)sniffer.arp_packet->target_protocol_address;
+                Ethernet_MAC *srcmac  = (Ethernet_MAC*)sniffer.arp_packet->sender_hardware_address;
+                IP_Address   *srcip   = (IP_Address*)sniffer.arp_packet->sender_protocol_address;
+                
+                your_mac = *srcmac;
+                
+                // Set the ARP options
+                *targmac = sniffer.mac;
+                *srcmac  = sniffer.mac;
+                *targip  = my_ip;
+                *srcip   = my_ip; 
+                sniffer.arp_packet->operation = 2;
+                
+                fix_endian_arp(sniffer.arp_packet);
+                sniffer.inject(BROADCAST_MAC, ETHERTYPE_ARP, sniffer.arp_packet, sizeof(ARP_Packet));
+                
+                while (!commands.empty())
+                {
+                    string command = commands.front();
+                    main_log.printf("NetTool> %s", command.c_str());
+                    if (command == "ping")
+                        ping_timer.attach(&ping, 30);
+                    else if (command == "portscan")
+                        scanner.start(sniffer.mac, your_mac, my_ip, your_ip);
+                    else if (command == "identify")
+                        identify();
+                    commands.pop();
+                }
+            }
+        }
+        else if (sniffer.tcp_packet)
+        {
+        }
+    }
+    
+    // This shouldn't really happen...
+    main_log.printf("Terminating...");
+    return 0;
+}
\ No newline at end of file