![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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.
scanner.h@5:c56386b9fc33, 2010-10-12 (annotated)
- Committer:
- etherealflaim
- Date:
- Tue Oct 12 06:37:21 2010 +0000
- Revision:
- 5:c56386b9fc33
- Parent:
- 4:88fc7fa58931
- Child:
- 6:66c4cd9073aa
Documentation enhancements
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
etherealflaim | 0:d494b853ce97 | 1 | #ifndef SCANNER_H |
etherealflaim | 0:d494b853ce97 | 2 | #define SCANNER_H |
etherealflaim | 0:d494b853ce97 | 3 | |
etherealflaim | 0:d494b853ce97 | 4 | #include "main.h" |
etherealflaim | 0:d494b853ce97 | 5 | #include "net/net.h" |
etherealflaim | 0:d494b853ce97 | 6 | #include "util/log.h" |
etherealflaim | 0:d494b853ce97 | 7 | #include "sniffer.h" |
etherealflaim | 0:d494b853ce97 | 8 | |
etherealflaim | 0:d494b853ce97 | 9 | #include <cstring> |
etherealflaim | 0:d494b853ce97 | 10 | #include <set> |
etherealflaim | 0:d494b853ce97 | 11 | |
etherealflaim | 0:d494b853ce97 | 12 | #define SCANNER_PADSIZE 0 |
etherealflaim | 0:d494b853ce97 | 13 | #define SCANNER_FRAMESIZE (sizeof(Ethernet_FrameHeader) + sizeof(IP_PacketHeader) + sizeof(TCP_SegmentHeader) + SCANNER_PADSIZE) |
etherealflaim | 0:d494b853ce97 | 14 | |
etherealflaim | 4:88fc7fa58931 | 15 | /// Demo - TCP Port Scanner |
etherealflaim | 0:d494b853ce97 | 16 | class Scanner |
etherealflaim | 0:d494b853ce97 | 17 | { |
etherealflaim | 0:d494b853ce97 | 18 | private: |
etherealflaim | 0:d494b853ce97 | 19 | Sniffer *sniffer; |
etherealflaim | 0:d494b853ce97 | 20 | Ticker scan_timer; |
etherealflaim | 0:d494b853ce97 | 21 | Timeout scan_timeout; |
etherealflaim | 0:d494b853ce97 | 22 | |
etherealflaim | 0:d494b853ce97 | 23 | u8 raw_frame[SCANNER_FRAMESIZE]; |
etherealflaim | 0:d494b853ce97 | 24 | |
etherealflaim | 0:d494b853ce97 | 25 | IP_Address destip; |
etherealflaim | 0:d494b853ce97 | 26 | u16 port_idx; |
etherealflaim | 0:d494b853ce97 | 27 | u16 pseudo_checksum; |
etherealflaim | 0:d494b853ce97 | 28 | |
etherealflaim | 0:d494b853ce97 | 29 | set<u16> open_ports; |
etherealflaim | 0:d494b853ce97 | 30 | |
etherealflaim | 0:d494b853ce97 | 31 | LocalFileSystem local; |
etherealflaim | 0:d494b853ce97 | 32 | |
etherealflaim | 0:d494b853ce97 | 33 | public: |
etherealflaim | 5:c56386b9fc33 | 34 | /// Constructor |
etherealflaim | 0:d494b853ce97 | 35 | inline Scanner(Sniffer *_sniffer) |
etherealflaim | 0:d494b853ce97 | 36 | : sniffer(_sniffer), local("local") |
etherealflaim | 0:d494b853ce97 | 37 | { |
etherealflaim | 0:d494b853ce97 | 38 | sniffer->attach_tcp(this, &Scanner::handle_tcp); |
etherealflaim | 0:d494b853ce97 | 39 | } |
etherealflaim | 0:d494b853ce97 | 40 | |
etherealflaim | 5:c56386b9fc33 | 41 | /// Handle incoming TCP packets |
etherealflaim | 0:d494b853ce97 | 42 | inline void handle_tcp(TCP_SegmentHeader *packet, u32 data_bytes) |
etherealflaim | 0:d494b853ce97 | 43 | { |
etherealflaim | 0:d494b853ce97 | 44 | if (packet->syn && packet->ack) |
etherealflaim | 0:d494b853ce97 | 45 | { |
etherealflaim | 0:d494b853ce97 | 46 | open_ports.insert(packet->source_port); |
etherealflaim | 0:d494b853ce97 | 47 | } |
etherealflaim | 0:d494b853ce97 | 48 | } |
etherealflaim | 0:d494b853ce97 | 49 | |
etherealflaim | 5:c56386b9fc33 | 50 | /// Handle the conclusion of the port scan (should not be called externally) |
etherealflaim | 0:d494b853ce97 | 51 | inline void finish() |
etherealflaim | 0:d494b853ce97 | 52 | { |
etherealflaim | 0:d494b853ce97 | 53 | FILE *fp = fopen("/local/PortScan.txt", "w"); |
etherealflaim | 0:d494b853ce97 | 54 | fprintf(fp, "Open Ports on %d.%d.%d.%d:\n", destip.octet[0], destip.octet[1], destip.octet[2], destip.octet[3]); |
etherealflaim | 0:d494b853ce97 | 55 | for (set<u16>::iterator iter = open_ports.begin(); iter != open_ports.end(); ++iter) |
etherealflaim | 0:d494b853ce97 | 56 | { |
etherealflaim | 0:d494b853ce97 | 57 | fprintf(fp, " TCP:%-5d OPEN\n", *iter); |
etherealflaim | 0:d494b853ce97 | 58 | } |
etherealflaim | 0:d494b853ce97 | 59 | fclose(fp); |
etherealflaim | 0:d494b853ce97 | 60 | |
etherealflaim | 0:d494b853ce97 | 61 | main_log.printf("Open ports:"); |
etherealflaim | 0:d494b853ce97 | 62 | for (set<u16>::iterator iter = open_ports.begin(); iter != open_ports.end(); ++iter) |
etherealflaim | 0:d494b853ce97 | 63 | { |
etherealflaim | 0:d494b853ce97 | 64 | main_log.printf(" TCP:%-5d OPEN", *iter); |
etherealflaim | 0:d494b853ce97 | 65 | } |
etherealflaim | 0:d494b853ce97 | 66 | main_log.printf("Port scan complete."); |
etherealflaim | 0:d494b853ce97 | 67 | } |
etherealflaim | 0:d494b853ce97 | 68 | |
etherealflaim | 5:c56386b9fc33 | 69 | /// Start a TCP port scan |
etherealflaim | 0:d494b853ce97 | 70 | inline void start(Ethernet_MAC src, Ethernet_MAC dst, IP_Address srcip, IP_Address dstip) |
etherealflaim | 0:d494b853ce97 | 71 | { |
etherealflaim | 0:d494b853ce97 | 72 | // Create the ethernet frame, IP packet, and TCP segment memory mapping |
etherealflaim | 0:d494b853ce97 | 73 | static Ethernet_FrameHeader *frame = (Ethernet_FrameHeader*)raw_frame; |
etherealflaim | 0:d494b853ce97 | 74 | static IP_PacketHeader *packet = (IP_PacketHeader*)frame->payload; |
etherealflaim | 0:d494b853ce97 | 75 | static TCP_SegmentHeader *segment = (TCP_SegmentHeader*)packet->data; |
etherealflaim | 0:d494b853ce97 | 76 | |
etherealflaim | 0:d494b853ce97 | 77 | destip = dstip; |
etherealflaim | 0:d494b853ce97 | 78 | main_log.printf("Starting TCP port scan of %d.%d.%d.%d...", dstip.octet[0], dstip.octet[1], dstip.octet[2], dstip.octet[3]); |
etherealflaim | 0:d494b853ce97 | 79 | |
etherealflaim | 0:d494b853ce97 | 80 | // Zero the frame |
etherealflaim | 0:d494b853ce97 | 81 | memset(raw_frame, '\0', SCANNER_FRAMESIZE); |
etherealflaim | 0:d494b853ce97 | 82 | |
etherealflaim | 0:d494b853ce97 | 83 | //sniffer->inject(dst, frame->ethertype, packet, 0); //sizeof(raw_frame)-sizeof(Ethernet_FrameHeader)); |
etherealflaim | 0:d494b853ce97 | 84 | |
etherealflaim | 0:d494b853ce97 | 85 | // Fill in the frame (constant for all TCP connections) |
etherealflaim | 0:d494b853ce97 | 86 | frame->destination = dst; |
etherealflaim | 0:d494b853ce97 | 87 | frame->source = src; |
etherealflaim | 0:d494b853ce97 | 88 | frame->ethertype = ETHERTYPE_IPV4; |
etherealflaim | 0:d494b853ce97 | 89 | |
etherealflaim | 0:d494b853ce97 | 90 | // Fill in the IP packet |
etherealflaim | 0:d494b853ce97 | 91 | packet->source = srcip; // Can't change with destination back-to-back? lol |
etherealflaim | 0:d494b853ce97 | 92 | packet->version = 0x04; |
etherealflaim | 0:d494b853ce97 | 93 | packet->header_bytes_div4 = 5; // *4 = 20 |
etherealflaim | 0:d494b853ce97 | 94 | packet->packet_bytes = SCANNER_FRAMESIZE-sizeof(Ethernet_FrameHeader); |
etherealflaim | 0:d494b853ce97 | 95 | packet->ttl = 64; |
etherealflaim | 0:d494b853ce97 | 96 | packet->protocol = IPPROTO_TCP; |
etherealflaim | 0:d494b853ce97 | 97 | packet->destination = dstip; |
etherealflaim | 0:d494b853ce97 | 98 | |
etherealflaim | 0:d494b853ce97 | 99 | // Fill in the TCP segment |
etherealflaim | 0:d494b853ce97 | 100 | segment->sequence_number = 0xBADBEEF0; |
etherealflaim | 0:d494b853ce97 | 101 | segment->data_offset_bytes_div4 = sizeof(TCP_SegmentHeader)/4; |
etherealflaim | 0:d494b853ce97 | 102 | segment->syn = 1; |
etherealflaim | 0:d494b853ce97 | 103 | segment->window_size = 8192; |
etherealflaim | 0:d494b853ce97 | 104 | pseudo_checksum = pseudo_header_checksum(srcip, dstip, sizeof(TCP_SegmentHeader)); |
etherealflaim | 0:d494b853ce97 | 105 | |
etherealflaim | 0:d494b853ce97 | 106 | // Initialize the scanning |
etherealflaim | 0:d494b853ce97 | 107 | port_idx = 0; |
etherealflaim | 0:d494b853ce97 | 108 | |
etherealflaim | 0:d494b853ce97 | 109 | open_ports.clear(); |
etherealflaim | 0:d494b853ce97 | 110 | scan_timer.attach_us(this, &Scanner::scan, 50); |
etherealflaim | 0:d494b853ce97 | 111 | //scan(); |
etherealflaim | 0:d494b853ce97 | 112 | } |
etherealflaim | 0:d494b853ce97 | 113 | |
etherealflaim | 5:c56386b9fc33 | 114 | /// Incremental scan updates (should not be called externally) |
etherealflaim | 0:d494b853ce97 | 115 | inline void scan() |
etherealflaim | 0:d494b853ce97 | 116 | { |
etherealflaim | 5:c56386b9fc33 | 117 | // Common ports... currently unused |
etherealflaim | 0:d494b853ce97 | 118 | static u16 ports[] = {1, 2, 3, 5, 7, 9, 11, 13, 17, 18, 19, 20, 21, 22, 23, 24, 25, 35, 37, 39, |
etherealflaim | 0:d494b853ce97 | 119 | 41, 42, 43, 47, 49, 50, 51, 52, 53, 54, 56, 58, 70, 79, 80, 83, 88, 90, 101, 102, |
etherealflaim | 0:d494b853ce97 | 120 | 104, 105, 107, 108, 109, 110, 111, 113, 113, 115, 117, 118, 119, 135, 137, 138, 139, 143, 152, 153, |
etherealflaim | 0:d494b853ce97 | 121 | 156, 162, 170, 177, 179, 194, 199, 201, 209, 210, 213, 218, 220, 259, 264, 308, 311, 318, 350, 351, |
etherealflaim | 0:d494b853ce97 | 122 | 366, 369, 371, 383, 384, 387, 389, 401, 427, 443, 444, 445, 464, 475, 497, 504, 512, 513, 514, 515, |
etherealflaim | 0:d494b853ce97 | 123 | 520, 524, 530, 532, 540, 542, 543, 544, 546, 547, 548, 554, 556, 563, 587, 591, 593, 604, 631, 635, |
etherealflaim | 0:d494b853ce97 | 124 | 636, 639, 641, 646, 647, 648, 653, 654, 657, 660, 674, 691, 692, 694, 695, 699, 700, 701, 702, 706, |
etherealflaim | 0:d494b853ce97 | 125 | 711, 712, 749, 750, 751, 752, 753, 754, 760, 860, 873, 902, 989, 990, 991, 992, 993, 995, 1058, |
etherealflaim | 0:d494b853ce97 | 126 | 1080, 1085, 1098, 1099, 1140, 1169, 1176, 1182, 1194, 1198, 1200, 1214, 1220, 1223, 1241, 1270, 1293, 1337, 1352, 1387, |
etherealflaim | 0:d494b853ce97 | 127 | 1414, 1417, 1418, 1419, 1420, 1431, 1433, 1470, 1494, 1512, 1513, 1521, 1524, 1533, 1547, 1677, 1720, 1723, 1755, 1761, |
etherealflaim | 0:d494b853ce97 | 128 | 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1801, 1812, 1813, 1863, 1935, 1947, 1970, 1971, 1972, 1984, 1994, 1998, 2000, |
etherealflaim | 0:d494b853ce97 | 129 | 2031, 2053, 2073, 2074, 2082, 2083, 2086, 2102, 2103, 2104, 2105, 2144, 2145, 2161, 2181, 2210, 2211, 2212, 2219, 2220, |
etherealflaim | 0:d494b853ce97 | 130 | 2261, 2262, 2369, 2370, 2404, 2447, 2483, 2484, 2500, 2612, 2713, 2714, 2735, 2809, 2868, 2947, 2948, 2949, 3050, 3051, |
etherealflaim | 0:d494b853ce97 | 131 | 3074, 3225, 3233, 3235, 3260, 3268, 3269, 3283, 3305, 3306, 3386, 3389, 3396, 3412, 3455, 3423, 3424, 3478, 3483, 3516, |
etherealflaim | 0:d494b853ce97 | 132 | 3532, 3533, 3606, 3632, 3689, 3690, 3702, 3880, 3868, 3900, 3945, 3999, 4018, 4089, 4093, 4096, 4111, 4116, 4321, 4662, |
etherealflaim | 0:d494b853ce97 | 133 | 4728, 4840, 4843, 4847, 4993, 4894, 4899, 4950, 5000, 5001, 5003, 5004, 5005, 5051, 5060, 5061, 5070, 5084, 5085, 5099, |
etherealflaim | 0:d494b853ce97 | 134 | 5151, 5154, 5190, 5222, 5269, 5298, 5351, 5355, 5402, 5405, 5421, 5432, 5556, 5631, 5814, 5900, 5984, 5999, 6000, 6005, |
etherealflaim | 0:d494b853ce97 | 135 | 6086, 6110, 6111, 6112, 6129, 6346, 6347, 6350, 6432, 6444, 6445, 6619, 6665, 6666, 6667, 6668, 6669, 6888, 6969, 7005, |
etherealflaim | 0:d494b853ce97 | 136 | 7006, 7400, 7401, 7402, 7547, 7787, 7788, 8000, 8008, 8078, 8080, 8118, 8123, 8243, 8280, 8400, 8442, 8880, 8888, 9009, |
etherealflaim | 0:d494b853ce97 | 137 | 9080, 9100, 9105, 9119, 9306, 9312, 9418, 9535, 9536, 9800, 9898, 9996, 10008, 10010, 10050, 10051, 10113, 10114, 10115, |
etherealflaim | 0:d494b853ce97 | 138 | 10116, 13076, 13720, 13721, 13724, 13782, 13783, 13785, 13786, 15000, 15345, 17500, 18104, 19283, 19315, 22347, 22350, |
etherealflaim | 0:d494b853ce97 | 139 | 24465, 24554, 26000, 31457, 33434, 40000, 43047, 43048, 47808}; |
etherealflaim | 0:d494b853ce97 | 140 | |
etherealflaim | 0:d494b853ce97 | 141 | // Create the ethernet frame, IP packet, and TCP segment memory mapping |
etherealflaim | 0:d494b853ce97 | 142 | static Ethernet_FrameHeader *frame = (Ethernet_FrameHeader*)raw_frame; |
etherealflaim | 0:d494b853ce97 | 143 | static IP_PacketHeader *packet = (IP_PacketHeader*)frame->payload; |
etherealflaim | 0:d494b853ce97 | 144 | static TCP_SegmentHeader *segment = (TCP_SegmentHeader*)packet->data; |
etherealflaim | 0:d494b853ce97 | 145 | |
etherealflaim | 0:d494b853ce97 | 146 | segment->source_port = port_idx; //ports[port_idx]; |
etherealflaim | 0:d494b853ce97 | 147 | segment->destination_port = port_idx; //ports[port_idx]; |
etherealflaim | 0:d494b853ce97 | 148 | |
etherealflaim | 0:d494b853ce97 | 149 | fix_endian_tcp(segment); |
etherealflaim | 0:d494b853ce97 | 150 | segment->checksum = checksum(segment, sizeof(TCP_SegmentHeader), &segment->checksum, sizeof(segment->checksum), pseudo_checksum); |
etherealflaim | 0:d494b853ce97 | 151 | |
etherealflaim | 0:d494b853ce97 | 152 | fix_endian_ip(packet); |
etherealflaim | 0:d494b853ce97 | 153 | packet->header_checksum = checksum(packet, sizeof(IP_PacketHeader), &packet->header_checksum, sizeof(packet->header_checksum)); |
etherealflaim | 0:d494b853ce97 | 154 | |
etherealflaim | 0:d494b853ce97 | 155 | fix_endian_ethernet(frame); |
etherealflaim | 0:d494b853ce97 | 156 | sniffer->inject(frame, SCANNER_FRAMESIZE); |
etherealflaim | 0:d494b853ce97 | 157 | |
etherealflaim | 0:d494b853ce97 | 158 | fix_endian_ethernet(frame); |
etherealflaim | 0:d494b853ce97 | 159 | fix_endian_ip(packet); |
etherealflaim | 0:d494b853ce97 | 160 | fix_endian_tcp(segment); |
etherealflaim | 0:d494b853ce97 | 161 | |
etherealflaim | 0:d494b853ce97 | 162 | // Update sequence number |
etherealflaim | 0:d494b853ce97 | 163 | segment->sequence_number++; |
etherealflaim | 0:d494b853ce97 | 164 | |
etherealflaim | 0:d494b853ce97 | 165 | //if (port_idx >= sizeof(ports)/sizeof(u16)) scan_timer.detach(); |
etherealflaim | 0:d494b853ce97 | 166 | if (port_idx >= 65535) |
etherealflaim | 0:d494b853ce97 | 167 | { |
etherealflaim | 0:d494b853ce97 | 168 | scan_timer.detach(); |
etherealflaim | 0:d494b853ce97 | 169 | scan_timeout.attach(this, &Scanner::finish, 7); |
etherealflaim | 0:d494b853ce97 | 170 | } |
etherealflaim | 0:d494b853ce97 | 171 | port_idx++; |
etherealflaim | 0:d494b853ce97 | 172 | } |
etherealflaim | 0:d494b853ce97 | 173 | }; |
etherealflaim | 0:d494b853ce97 | 174 | |
etherealflaim | 0:d494b853ce97 | 175 | #endif |