Changeset 3197b50 in mainline for uspace/app/pcapcat/main.c
- Timestamp:
- 2024-12-21T19:18:04Z (10 months ago)
- Children:
- 373dded
- Parents:
- fc632e8
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/pcapcat/main.c
rfc632e8 r3197b50 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 //qemu-system-x86_64 -m 256m -nic bridge,id=n1,mac=52:54:00:BE:EF:01,br=br0 -boot order=d -cdrom image.iso -serial stdio 28 29 29 30 30 #include <stdint.h> … … 35 35 #include <errno.h> 36 36 #include <str.h> 37 #include <getopt.h> 37 38 #include <io/log.h> 38 #include "pcap.h" 39 #include <pcap.h> 40 41 #include "linktype_parser.h" 42 #include "eth_parser.h" 39 43 40 44 #define NAME "pcapcat" 41 45 42 typedef struct { 43 uint32_t linktype; 44 void (*parse)(const char *); 45 } linktype_parser_t; 46 static const linktype_parser_t eth_parser = { 47 .parse_packets = ð_parse_packets, 48 .parse_file_header = ð_parse_header, 49 .linktype = PCAP_LINKTYPE_ETHERNET 50 }; 46 51 47 #define PRINT_IP(msg, ip_addr, spaces) printf("%s IP: %d.%d.%d.%d%s", msg, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces) 48 #define PRINT_MAC(msg, mac, spaces) printf("%s MAC: %x:%x:%x:%x:%x:%x%s", msg, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], spaces) 52 static const linktype_parser_t parsers[1] = {eth_parser}; 49 53 50 static void parse_arp(unsigned char *byte_source, size_t size) 51 { 52 uint8_t sender_mac[6]; 53 uint8_t sender_ip[4]; 54 uint8_t target_mac[6]; 55 uint8_t target_ip[4]; 56 57 for (int i = 22; i < 28; ++i) { 58 sender_mac[i - 22] = byte_source[i]; 59 } 60 61 for (int i = 28; i < 32; ++i) { 62 sender_ip[i - 28] = byte_source[i]; 63 } 64 65 for (int i = 32; i < 38; ++i) { 66 target_mac[i - 32] = byte_source[i]; 67 } 68 69 for (int i = 38; i < 42; ++i) { 70 target_ip[i - 38] = byte_source[i]; 71 } 72 73 PRINT_MAC("Sender", sender_mac, ", "); 74 PRINT_IP("Sender", sender_ip, " "); 75 PRINT_MAC("Target", target_mac, ", "); 76 PRINT_IP("Target", target_ip, "\n"); 77 78 } 79 80 static void parse_tcp(unsigned char *byte_source, size_t size) 81 { 82 uint16_t src_port = byte_source[34] << 8 | byte_source[35]; 83 uint16_t dst_port = byte_source[36] << 8 | byte_source[37]; 84 printf(" [TCP] source port: %d, destination port: %d\n", src_port, dst_port); 85 } 86 87 static void parse_ip(unsigned char *byte_source, size_t size) 88 { 89 uint16_t total_length; 90 uint8_t header_length; 91 uint16_t payload_length; 92 uint8_t protocol; 93 uint8_t src_ip[4]; 94 uint8_t dst_ip[4]; 95 96 header_length = (byte_source[14] & 0xf) * 4; 97 total_length = byte_source[16] << 8 | byte_source[17]; 98 payload_length = total_length - header_length; 99 protocol = byte_source[23]; 100 101 for (int i = 26; i < 30; ++i) { 102 src_ip[i - 26] = byte_source[i]; 103 } 104 for (int i = 30; i < 34; ++i) { 105 dst_ip[i - 30] = byte_source[i]; 106 } 107 printf("IP header: %dB, payload: %dB, protocol: 0x%x, ", header_length, payload_length, protocol); 108 PRINT_IP("Source", src_ip, ", "); 109 PRINT_IP("Destination", dst_ip, "\n"); 110 111 if (protocol == 0x6) { 112 parse_tcp(byte_source, size); 113 } 114 } 115 116 117 static void parse_packet(void *data, size_t size) 118 { 119 unsigned char* byte_source = (unsigned char*)data; 120 121 // Read the 12th and 13th bytes (indices 11 and 12) 122 unsigned char high_byte = byte_source[12]; // MSB 123 unsigned char low_byte = byte_source[13]; // LSB 124 125 // Combine bytes in big-endian order 126 uint16_t value = (high_byte << 8) | low_byte; 127 128 switch (value){ 129 case 0x0806: 130 printf("[ARP] "); 131 parse_arp(byte_source, size); 132 break; 133 case 0x0800: 134 printf("[IPv4] "); 135 parse_ip(byte_source, size); 136 break; 137 case 0x86DD: 138 printf("IPv6\n"); 139 break; 140 default: 141 printf("0x%x\n", value); 142 break; 143 } 144 //printf("Ethernet Type of packet: 0x%x\n", hdr->etype_len); 145 } 146 147 static void read_head(FILE *file) 148 { 149 pcap_file_header_t data; 150 memset(&data, 0, sizeof(pcap_file_header_t)); 151 152 size_t bytesRead = fread(&data, 1, sizeof(pcap_file_header_t), file); 153 if (bytesRead < sizeof(pcap_file_header_t)) { 154 printf("Error: Could not read enough bytes (read %zu bytes)\n", bytesRead); 155 fclose(file); 156 return; 157 } 158 159 printf("LinkType: %d\n", data.additional); 160 printf("Magic number: 0x%x\n", data.magic_number); 161 return; 162 } 163 164 static void eth_parse(const char *file_path) 54 static int parse_file(const char *file_path, int packet_count, bool verbose_flag) 165 55 { 166 56 FILE *f = fopen(file_path, "rb"); 167 57 if (f == NULL){ 168 58 printf("File %s does not exist.\n", file_path); 169 return ;59 return 1; 170 60 } 171 61 172 read_head(f); 62 pcap_file_header_t hdr; 63 memset(&hdr, 0, sizeof(pcap_file_header_t)); 173 64 174 pcap_packet_header_t hdr; 175 176 memset(&hdr, 0, sizeof(pcap_packet_header_t)); 177 size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); 178 int index = 1; 179 while (read_bytes > 0) 180 { 181 if (read_bytes < sizeof(pcap_packet_header_t)) { 182 printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes); 183 return; 184 } 185 printf("%04d) ", index); 186 index++; 187 //printf("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length); 188 void *data = malloc(hdr.captured_length); 189 fread(data, 1, (size_t)hdr.captured_length, f); 190 parse_packet(data, (size_t)hdr.captured_length); 191 free(data); 192 read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); 65 size_t bytes_read = fread(&hdr, 1, sizeof(pcap_file_header_t), f); 66 if (bytes_read < sizeof(pcap_file_header_t)) { 67 printf("Error: Could not read enough bytes (read %zu bytes)\n", bytes_read); 68 fclose(f); 69 return 1; 193 70 } 194 71 195 fclose(f); 72 int parser_count = sizeof(parsers) / sizeof(linktype_parser_t); 73 int parser_index = -1; 74 for (int i = 0; i < parser_count; ++i) { 75 if (parsers[i].linktype == hdr.additional) { 76 parser_index = i; 77 break; 78 } 79 } 80 81 if (parser_index == -1) { 82 printf("There is no parser for Linktype %d.\n", hdr.additional); 83 return 1; 84 } 85 86 parsers[parser_index].parse_file_header(&hdr); 87 parsers[parser_index].parse_packets(f, packet_count, verbose_flag); 88 return 0; 196 89 } 197 90 198 static const linktype_parser_t eth_parser = { 199 .parse = ð_parse, 200 .linktype = PCAP_LINKTYPE_ETHERNET 91 static void usage() 92 { 93 printf("HelenOS cat utility for PCAP file format.\n" 94 "Can run during dumping process.\n" 95 "Usage:\n" 96 NAME " <filename>\n" 97 "\tPrint all packets from file <filename>.\n" 98 NAME " --count= | -c <number> <filename>\n" 99 "\tPrint first <number> packets from <filename>.\n" 100 NAME " --verbose | -v <filename>\n" 101 "\tPrint verbose description (with TCP ports) of packets.\n" 102 ); 103 } 104 105 static struct option options[] = { 106 {"count", required_argument, 0, 'c'}, 107 {"verbose", no_argument, 0, 'v'}, 108 {0, 0, 0, 0} 201 109 }; 202 110 … … 204 112 int main(int argc, char *argv[]) 205 113 { 206 if (argc != 2) 114 int ret = 0; 115 int idx = 0; 116 int count = -1; 117 bool verbose = false; 118 const char *filename = ""; 119 if (argc == 1) 207 120 { 208 return 1; 121 usage(); 122 return 0; 209 123 } 210 124 211 eth_parser.parse(argv[1]); 125 while (ret != -1) { 126 ret = getopt_long(argc, argv, "c:v", options, &idx); 127 switch (ret) 128 { 129 case 'c': 130 count = atoi(optarg); 131 break; 132 case 'v': 133 verbose = true; 134 break; 135 case '?': 136 printf("Unknown option or missing argument.\n"); 137 return 1; 138 default: 139 break; 140 } 141 } 212 142 213 return 0; 143 if (optind < argc) { 144 filename = argv[optind]; 145 } 146 147 int ret_val = parse_file(filename, count, verbose); 148 149 return ret_val; 214 150 }
Note:
See TracChangeset
for help on using the changeset viewer.