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.
Diff: main.cpp
- 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