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.
main.cpp
- Committer:
- etherealflaim
- Date:
- 2010-10-12
- Revision:
- 7:e34ae4c7eb79
- Parent:
- 6:66c4cd9073aa
File content as of revision 7:e34ae4c7eb79:
#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> /** \file main.cpp \brief This is the primary NetTool demo file. This file is the brains of the NetTool, utilizing the networking code found in other files to do some basic network diagnostic stuff. Note that for the nettool to connect to a computer, the computer has to already have an IP configured on the interface, which usually requires that the interface or connection be manually assigned an IP address. */ // 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; }