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:
- 0:d494b853ce97
- Child:
- 6:66c4cd9073aa
File content as of revision 0:d494b853ce97:
#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; }