Changeset caac052 in mainline
- Timestamp:
- 2024-12-22T16:47:50Z (10 months ago)
- Children:
- 46e2152
- Parents:
- 373dded
- Location:
- uspace
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/pcapcat/eth_parser.c
r373dded rcaac052 27 27 */ 28 28 29 /** @addtogroup pcapcat 30 * @{ 31 */ 32 /** @file Implementation of functions for parsing PCAP file of LinkType 1 (LINKTYPE_ETHERNET). 33 */ 29 34 30 35 #include <stdint.h> 31 36 #include <stdio.h> 32 37 #include <stdlib.h> 33 #include <time.h>34 38 #include <stdbool.h> 35 #include <errno.h>36 39 #include <str.h> 37 #include <io/log.h> 38 #include "pcap.h" 40 #include <pcap.h> 39 41 #include "eth_parser.h" 40 42 41 43 #define ETH_ADDR_SIZE 6 42 44 #define IPV4_ADDR_SIZE 4 45 #define TCP_PORT_SIZE 2 43 46 44 47 #define ETHER_TYPE_ARP 0x0806 … … 47 50 48 51 #define BYTE_SIZE 8 52 #define HDR_SIZE_COEF 4 53 #define LOWER_4_BITS 0xf 49 54 50 55 #define IP_PROTOCOL_TCP 0x06 … … 58 63 #define IPV4_TEXT "IPv4" 59 64 #define IPV6_TEXT "IPv6" 65 #define MALFORMED_PACKET "packet is malformed.\n" 60 66 61 67 #define PRINT_IP(msg, ip_addr, spaces) printf("%s %s: %d.%d.%d.%d%s", msg, IP_TEXT, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces) … … 63 69 #define BIG_END_16(buffer, idx) buffer[idx] << BYTE_SIZE | buffer[idx + 1] 64 70 65 66 static void read_from_buffer(unsigned char *buffer, int start_idx, int count, uint8_t *dst) 67 { 68 for (int i = start_idx; i < start_idx + count; ++i) { 71 /** Read count bytes from char buffer. 72 * @param buffer of bytes to read from. 73 * @param start_idx index of the first byte to read. 74 * @param count number of byte to read. 75 * @param dst destination buffer. 76 */ 77 static void read_from_buffer(unsigned char *buffer, size_t start_idx, size_t count, uint8_t *dst) 78 { 79 for (size_t i = start_idx; i < start_idx + count; ++i) { 69 80 dst[i - start_idx] = buffer[i]; 70 81 } 71 82 } 72 83 73 static void parse_arp(unsigned char *byte_source, size_t size) 74 { 84 /** Parse ARP packet and print out addresses. 85 * @param buffer ARP packet. 86 * @param size Size of the packet. 87 */ 88 static void parse_arp(unsigned char *buffer, size_t size) 89 { 90 size_t sender_mac_offset = 22; 91 size_t sender_ip_offset = 28; 92 size_t target_mac_offset = 32; 93 size_t target_ip_offset = 38; 94 if (size < target_ip_offset + IPV4_ADDR_SIZE) { 95 printf("%s %s", ARP_TEXT, MALFORMED_PACKET); 96 return; 97 } 98 75 99 uint8_t sender_mac[ETH_ADDR_SIZE]; 76 100 uint8_t sender_ip[IPV4_ADDR_SIZE]; … … 78 102 uint8_t target_ip[IPV4_ADDR_SIZE]; 79 103 80 read_from_buffer(b yte_source, 22, ETH_ADDR_SIZE, sender_mac);81 read_from_buffer(b yte_source, 28, IPV4_ADDR_SIZE, sender_ip);82 read_from_buffer(b yte_source, 32, ETH_ADDR_SIZE, target_mac);83 read_from_buffer(b yte_source, 36, IPV4_ADDR_SIZE, target_ip);104 read_from_buffer(buffer, sender_mac_offset, ETH_ADDR_SIZE, sender_mac); 105 read_from_buffer(buffer, sender_ip_offset, IPV4_ADDR_SIZE, sender_ip); 106 read_from_buffer(buffer, target_mac_offset, ETH_ADDR_SIZE, target_mac); 107 read_from_buffer(buffer, target_ip_offset, IPV4_ADDR_SIZE, target_ip); 84 108 85 109 PRINT_MAC("Sender", sender_mac, ", "); … … 87 111 PRINT_MAC("Target", target_mac, ", "); 88 112 PRINT_IP("Target", target_ip, "\n"); 89 90 } 91 92 static void parse_tcp(unsigned char *byte_source, size_t size) 93 { 94 uint16_t src_port = BIG_END_16(byte_source, 34); 95 uint16_t dst_port = BIG_END_16(byte_source, 36); 113 } 114 115 /** Parce TCP and print ports. 116 * @param buffer TCP segment. 117 * @param size of the buffer. 118 */ 119 static void parse_tcp(unsigned char *buffer, size_t size) 120 { 121 size_t src_port_offset = 34; 122 size_t dst_port_offset = 36; 123 124 if (size < dst_port_offset + TCP_PORT_SIZE) { 125 printf("%s %s\n", TCP_TEXT, MALFORMED_PACKET); 126 return; 127 } 128 129 uint16_t src_port = BIG_END_16(buffer, src_port_offset); 130 uint16_t dst_port = BIG_END_16(buffer, dst_port_offset); 96 131 printf(" [%s] source port: %d, destination port: %d\n", TCP_TEXT, src_port, dst_port); 97 132 } 98 133 99 static void parse_ip(unsigned char *byte_source, size_t size, bool verbose) 134 /** Parse IP and print interesting parts. 135 * @param buffer IP packet. 136 * @param size size of the buffer. 137 * @param verbose verbosity flag. 138 */ 139 static void parse_ip(unsigned char *buffer, size_t size, bool verbose) 100 140 { 101 141 uint16_t total_length; … … 106 146 uint8_t dst_ip[IPV4_ADDR_SIZE]; 107 147 108 header_length = (byte_source[14] & 0xf) * 4; 109 total_length = BIG_END_16(byte_source, 16); 148 size_t hdr_length_offset = 14; 149 size_t total_len_offset = 16; 150 size_t protocol_offset = 23; 151 size_t src_ip_offset = 26; 152 size_t dst_ip_offset = 30; 153 154 if (size < dst_ip_offset + IPV4_ADDR_SIZE) { 155 printf("%s %s", IP_TEXT, MALFORMED_PACKET); 156 return; 157 } 158 159 header_length = (buffer[hdr_length_offset] & LOWER_4_BITS) * HDR_SIZE_COEF; 160 total_length = BIG_END_16(buffer, total_len_offset); 110 161 payload_length = total_length - header_length; 111 ip_protocol = b yte_source[23];112 113 read_from_buffer(b yte_source, 26, IPV4_ADDR_SIZE, src_ip);114 read_from_buffer(b yte_source, 28, IPV4_ADDR_SIZE, dst_ip);162 ip_protocol = buffer[protocol_offset]; 163 164 read_from_buffer(buffer, src_ip_offset, IPV4_ADDR_SIZE, src_ip); 165 read_from_buffer(buffer, dst_ip_offset, IPV4_ADDR_SIZE, dst_ip); 115 166 116 167 printf("%s header: %dB, payload: %dB, protocol: 0x%x, ", IP_TEXT, header_length, payload_length, ip_protocol); … … 119 170 120 171 if (verbose && ip_protocol == IP_PROTOCOL_TCP) { 121 parse_tcp(byte_source, size); 122 } 123 } 124 125 static void parse_eth_packet(void *data, size_t size, bool verbose_flag) 126 { 127 unsigned char* byte_source = (unsigned char*)data; 128 129 uint16_t protocol = BIG_END_16(byte_source, 12); 172 parse_tcp(buffer, size); 173 } 174 } 175 176 /** Parse ethernnet frame based on eth_type of the frame. 177 * @param data Ethernet frame. 178 * @param size Size of the frame. 179 * @param verbose_flag Verbosity flag. 180 */ 181 static void parse_eth_frame(void *data, size_t size, bool verbose_flag) 182 { 183 unsigned char* buffer = (unsigned char*)data; 184 185 size_t eth_type_offset = 12; 186 uint16_t protocol = BIG_END_16(buffer, eth_type_offset); 130 187 131 188 switch (protocol){ 132 189 case ETHER_TYPE_ARP: 133 190 printf("[%s] ", ARP_TEXT); 134 parse_arp(b yte_source, size);191 parse_arp(buffer, size); 135 192 break; 136 193 case ETHER_TYPE_IP4: 137 194 printf("[%s] ", IPV4_TEXT); 138 parse_ip(b yte_source, size, verbose_flag);195 parse_ip(buffer, size, verbose_flag); 139 196 break; 140 197 case ETHER_TYPE_IP6: … … 147 204 } 148 205 206 /** Parse file header of PCAP file. 207 * @param hdr PCAP header structure. 208 */ 149 209 void eth_parse_header(pcap_file_header_t *hdr) 150 210 { … … 153 213 } 154 214 155 void eth_parse_packets(FILE *f, int count, bool verbose_flag) 215 /** Parse PCAP file. 216 * @param pcap_file file of PCAP format with dumped packets. 217 * @param count number of packets to be parsed and printed from file (if -1 all packets are printed). 218 * @param verbose_flag verbosity flag. 219 */ 220 void eth_parse_frames(FILE *pcap_file, int count, bool verbose_flag) 156 221 { 157 222 pcap_packet_header_t hdr; 158 223 159 size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f);224 size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file); 160 225 int packet_index = 1; 161 226 while (read_bytes > 0) … … 169 234 170 235 void *data = malloc(hdr.captured_length); 171 read_bytes = fread(data, 1, (size_t)hdr.captured_length, f);236 read_bytes = fread(data, 1, (size_t)hdr.captured_length, pcap_file); 172 237 if (read_bytes < (size_t)hdr.captured_length) { 173 238 printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes); 174 239 return; 175 240 } 176 parse_eth_ packet(data, (size_t)hdr.captured_length, verbose_flag);241 parse_eth_frame(data, (size_t)hdr.captured_length, verbose_flag); 177 242 free(data); 178 243 179 //Read first count packets 244 //Read first count packets from file. 180 245 if (count != -1 && count == packet_index - 1) { 181 246 return; … … 183 248 184 249 memset(&hdr, 0, sizeof(pcap_packet_header_t)); 185 read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f); 186 } 187 188 fclose(f); 189 } 250 read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file); 251 } 252 253 fclose(pcap_file); 254 } 255 256 /** @} 257 */ -
uspace/app/pcapcat/eth_parser.h
r373dded rcaac052 27 27 */ 28 28 29 /** @addtogroup pcapcat 30 * @{ 31 */ 32 /** @file Functions for parsing PCAP file of LinkType 1 (LINKTYPE_ETHERNET). 33 */ 29 34 30 35 #include <stdint.h> … … 35 40 #include <errno.h> 36 41 #include <str.h> 37 #include <io/log.h>38 42 #include <pcap.h> 39 43 40 extern void eth_parse_ packets(FILE *, int, bool);44 extern void eth_parse_frames(FILE *, int, bool); 41 45 extern void eth_parse_header(pcap_file_header_t *); 46 47 /** @} 48 */ -
uspace/app/pcapcat/linktype_parser.h
r373dded rcaac052 27 27 */ 28 28 29 #include <stdint.h> 30 #include <stdio.h> 29 /** @addtogroup pcapcat 30 * @{ 31 */ 32 /** @file Structure for parsing PCAP file. 33 */ 34 31 35 #include <stdlib.h> 32 #include <time.h>33 36 #include <stdbool.h> 34 #include <errno.h>35 37 #include <str.h> 36 #include <io/log.h>37 38 #include <pcap.h> 38 39 39 40 40 typedef struct { … … 43 43 void (*parse_packets)(FILE *, int, bool); 44 44 } linktype_parser_t; 45 46 /** @} 47 */ -
uspace/app/pcapcat/main.c
r373dded rcaac052 45 45 46 46 static const linktype_parser_t eth_parser = { 47 .parse_packets = ð_parse_ packets,47 .parse_packets = ð_parse_frames, 48 48 .parse_file_header = ð_parse_header, 49 49 .linktype = PCAP_LINKTYPE_ETHERNET -
uspace/app/pcapctl/doc/doxygroups.h
r373dded rcaac052 1 1 /** @addtogroup pcapctl pcapctl 2 * @brief Dump network packets2 * @brief Command-line utility for dumping packets. 3 3 * @ingroup apps 4 4 */ -
uspace/lib/pcap/include/pcap.h
r373dded rcaac052 95 95 }; 96 96 97 extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype , bool nano);97 extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype); 98 98 extern void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, size_t size); 99 99 extern void pcap_set_time(pcap_packet_header_t *header); -
uspace/lib/pcap/src/pcap.c
r373dded rcaac052 48 48 getrealtime(&ts); 49 49 header->seconds_stamp = (uint32_t)ts.tv_sec; 50 header->magic_stamp = (uint32_t)ts.tv_ nsec;50 header->magic_stamp = (uint32_t)ts.tv_sec / 1000; 51 51 } 52 52 … … 55 55 * @param writer Writer that has destination buffer and ops to write to destination buffer. 56 56 * @param linktype Linktype for the file header. 57 * @param nano True for nanoseconds, false for microseconds in timestamp.58 57 */ 59 void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype , bool nano)58 void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype) 60 59 { 61 uint32_t magic_version = PCAP_MAGIC_MICRO; 62 if (nano) { 63 magic_version = PCAP_MAGIC_NANO; 64 } 65 pcap_file_header_t file_header = { magic_version, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, 60 pcap_file_header_t file_header = { (uint32_t)PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION, 66 61 0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, linktype }; 67 62 writer->ops->write_buffer(writer, &file_header, sizeof(file_header)); -
uspace/lib/pcap/src/pcap_dumper.c
r373dded rcaac052 60 60 return EINVAL; 61 61 } 62 pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET , false);62 pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET); 63 63 64 64 return EOK; … … 98 98 return EINVAL; 99 99 } 100 pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED , false);100 pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED); 101 101 102 102 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.