- Timestamp:
- 02/05/19 09:50:43 (2 years ago)
- Branches:
- develop
- Children:
- 5e5b6ca
- Parents:
- db919d5 (diff), 1c3f8d2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Location:
- lib
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
lib/format_dag25.c
r8c5c550 rfce4572 174 174 * many times or close a device that we're still using */ 175 175 struct dag_dev_t *open_dags = NULL; 176 177 static bool dag_can_write(libtrace_packet_t *packet) { 178 /* Get the linktype */ 179 libtrace_linktype_t ltype = trace_get_link_type(packet); 180 181 if (ltype == TRACE_TYPE_CONTENT_INVALID) { 182 return false; 183 } 184 185 /* TODO erf meta should definitely be writable, pcapng meta 186 * could probably be converted into erf meta */ 187 if (ltype == TRACE_TYPE_ERF_META 188 || ltype == TRACE_TYPE_NONDATA 189 || ltype == TRACE_TYPE_PCAPNG_META) { 190 return false; 191 } 192 193 return true; 194 } 176 195 177 196 /* Returns the amount of padding between the ERF header and the start of the … … 1186 1205 static int dag_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) 1187 1206 { 1207 /* Check dag can write this type of packet */ 1208 if (!dag_can_write(packet)) { 1209 return 0; 1210 } 1211 1188 1212 /* This is heavily borrowed from erf_write_packet(). Yes, CnP 1189 1213 * coding sucks, sorry about that. … … 1200 1224 return -1; 1201 1225 } 1202 1203 if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)1204 return 0;1205 1226 1206 1227 pad = dag_get_padding(packet); -
lib/format_dpdk.c
r10fd24b r4d390c0 145 145 }; 146 146 147 static bool dpdk_can_write(libtrace_packet_t *packet) { 148 libtrace_linktype_t ltype = trace_get_link_type(packet); 149 150 if (ltype == TRACE_TYPE_CONTENT_INVALID) { 151 return false; 152 } 153 if (ltype == TRACE_TYPE_NONDATA || ltype == TRACE_TYPE_ERF_META || 154 ltype == TRACE_TYPE_PCAPNG_META) { 155 return false; 156 } 157 return true; 158 } 159 147 160 /** 148 161 * We want to blacklist all devices except those on the whitelist … … 255 268 if((file = fopen(path, "r")) != NULL) { 256 269 int numa_node = -1; 257 fscanf(file, "%d", &numa_node); 270 if (fscanf(file, "%d", &numa_node) != 1) { 271 numa_node = -1; 272 } 258 273 fclose(file); 259 274 return numa_node; … … 875 890 if (port != format_data->port) { 876 891 fprintf(stderr, "Port does not match port in format data in dpdk_lsc_callback()\n"); 877 return -1; 892 #if RTE_VERSION >= RTE_VERSION_NUM(17, 8, 0, 1) 893 return -1; 894 #else 895 return; 896 #endif 878 897 } 879 898 … … 1557 1576 static int dpdk_write_packet(libtrace_out_t *trace, 1558 1577 libtrace_packet_t *packet){ 1578 1579 /* Check dpdk can write this type of packet */ 1580 if (!dpdk_can_write(packet)) { 1581 return 0; 1582 } 1583 1559 1584 struct rte_mbuf* m_buff[1]; 1560 1585 -
lib/format_erf.c
rd439067 r2d16fc7 119 119 } erf_index_t; 120 120 121 static bool erf_can_write(libtrace_packet_t *packet) { 122 /* Get the linktype */ 123 libtrace_linktype_t ltype = trace_get_link_type(packet); 124 125 if (ltype == TRACE_TYPE_CONTENT_INVALID) { 126 return false; 127 } 128 if (ltype == TRACE_TYPE_PCAPNG_META 129 || ltype == TRACE_TYPE_NONDATA) { 130 131 return false; 132 } 133 134 return true; 135 } 136 121 137 /* Ethernet packets have a 2 byte padding before the packet 122 138 * so that the IP header is aligned on a 32 bit boundary. … … 670 686 libtrace_packet_t *packet) 671 687 { 688 689 /* Check erf can write this type of packet */ 690 if (!erf_can_write(packet)) { 691 return 0; 692 } 693 672 694 int numbytes = 0; 673 695 dag_record_t *dag_hdr = (dag_record_t *)packet->header; … … 679 701 return -1; 680 702 } 681 682 if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)683 return 0;684 703 685 704 if (!packet->header) { … … 770 789 dag_record_t *erfptr = 0; 771 790 erfptr = (dag_record_t *)packet->header; 772 uint8_t type = (erfptr->type & 0x7f); 791 uint8_t type; 792 793 if (packet->header == NULL) { 794 return ~0; 795 } 796 797 type = (erfptr->type & 0x7f); 773 798 if (type != TYPE_LEGACY) { 774 799 /* The top-most bit is now used to indicate the presence of … … 777 802 } 778 803 else { 804 if (trace_get_capture_length(packet) < 5 || 805 packet->payload == NULL) { 806 return ~0; 807 } 808 779 809 /* Sigh, lets start wildly guessing */ 780 810 if (((char*)packet->payload)[4]==0x45) … … 787 817 dag_record_t *erfptr = 0; 788 818 erfptr = (dag_record_t *)packet->header; 789 return erfptr->flags.iface; 819 if (packet->header) { 820 return erfptr->flags.iface; 821 } 822 return TRACE_DIR_UNKNOWN; 790 823 } 791 824 … … 793 826 dag_record_t *erfptr = 0; 794 827 erfptr = (dag_record_t *)packet->header; 828 829 if (packet->header == NULL) { 830 return TRACE_DIR_UNKNOWN; 831 } 795 832 erfptr->flags.iface = direction; 796 833 return erfptr->flags.iface; … … 800 837 dag_record_t *erfptr = 0; 801 838 erfptr = (dag_record_t *)packet->header; 839 840 if (erfptr == NULL) { 841 return 0; 842 } 802 843 return bswap_le_to_host64(erfptr->ts); 803 844 } … … 809 850 uint16_t wlen, rlen; 810 851 811 if (packet->payload == NULL )852 if (packet->payload == NULL || packet->header == NULL) 812 853 return 0; 813 854 … … 828 869 erfptr = (dag_record_t *)packet->header; 829 870 871 if (packet->header == NULL) { 872 return 0; 873 } 874 830 875 if ((erfptr->type & 0x7f) == TYPE_META) 831 876 return 0; … … 843 888 } 844 889 erfptr = (dag_record_t *)packet->header; 890 891 if (packet->header == NULL) { 892 return ~0U; 893 } 845 894 846 895 if(size > trace_get_capture_length(packet) || (erfptr->type & 0x7f) == TYPE_META) { -
lib/format_etsilive.c
rccabd47 rb359a11 362 362 sizeof(etsisocket_t) * (et->sourcealloc + 10)); 363 363 364 for (i = et->sourcealloc; i < et->sourcealloc + 10; 365 i++) { 366 et->sources[i].sock = -1; 367 et->sources[i].srcaddr = NULL; 368 } 364 369 esock = &(et->sources[et->sourcealloc]); 365 370 et->sourcealloc += 10; -
lib/format_linux_common.c
r509ee47 r5fe998b 70 70 pcap_t *pcap; 71 71 72 /* Take a copy of the filter object as it was passed in */ 73 f = (libtrace_filter_t *) malloc(sizeof(libtrace_filter_t)); 74 memcpy(f, filter, sizeof(libtrace_filter_t)); 72 /* Take a copy of the filter structure to prevent against 73 * deletion causing the filter to no longer work */ 74 f = (libtrace_filter_t *) malloc(sizeof(libtrace_filter_t)); 75 memset(f, 0, sizeof(libtrace_filter_t)); 76 memcpy(f, filter, sizeof(libtrace_filter_t)); 77 f->filterstring = strdup(filter->filterstring); 75 78 76 79 /* If we are passed a filter with "flag" set to zero, then we must … … 120 123 121 124 if (FORMAT_DATA->filter != NULL) 122 free(FORMAT_DATA->filter);125 trace_destroy_filter(FORMAT_DATA->filter); 123 126 124 127 FORMAT_DATA->filter = f; … … 498 501 if (libtrace->format_data) { 499 502 if (FORMAT_DATA->filter != NULL) 500 free(FORMAT_DATA->filter);503 trace_destroy_filter(FORMAT_DATA->filter); 501 504 502 505 if (FORMAT_DATA->per_stream) -
lib/format_linux_int.c
rd439067 re9fe6ac 53 53 #include "format_linux_common.h" 54 54 55 #define SLL_HEADER_LENGTH 6 55 56 56 57 #ifdef HAVE_NETPACKET_PACKET_H 57 58 59 static bool linuxnative_can_write(libtrace_packet_t *packet) { 60 /* Get the linktype */ 61 libtrace_linktype_t ltype = trace_get_link_type(packet); 62 63 if (ltype == TRACE_TYPE_NONDATA) { 64 return false; 65 } 66 if (ltype == TRACE_TYPE_CONTENT_INVALID) { 67 return false; 68 } 69 if (ltype == TRACE_TYPE_PCAPNG_META) { 70 return false; 71 } 72 if (ltype == TRACE_TYPE_ERF_META) { 73 return false; 74 } 75 76 return true; 77 } 58 78 59 79 static int linuxnative_start_input(libtrace_t *libtrace) … … 336 356 libtrace_packet_t *packet) 337 357 { 358 /* Check linuxnative can write this type of packet */ 359 if (!linuxnative_can_write(packet)) { 360 return 0; 361 } 362 338 363 struct sockaddr_ll hdr; 339 364 int ret = 0; 340 341 if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)342 return 0;343 365 344 366 hdr.sll_family = AF_PACKET; … … 347 369 hdr.sll_hatype = 0; 348 370 hdr.sll_pkttype = 0; 349 hdr.sll_halen = htons( 6); /* FIXME */350 memcpy(hdr.sll_addr,packet->payload,(size_t) ntohs(hdr.sll_halen));371 hdr.sll_halen = htons(SLL_HEADER_LENGTH); /* FIXME */ 372 memcpy(hdr.sll_addr,packet->payload,(size_t)SLL_HEADER_LENGTH); 351 373 352 374 /* This is pretty easy, just send the payload using sendto() (after -
lib/format_linux_ring.c
rd439067 rfce4572 71 71 static int pagesize = 0; 72 72 73 static bool linuxring_can_write(libtrace_packet_t *packet) { 74 /* Get the linktype */ 75 libtrace_linktype_t ltype = trace_get_link_type(packet); 76 77 if (ltype == TRACE_TYPE_CONTENT_INVALID) { 78 return false; 79 } 80 if (ltype == TRACE_TYPE_NONDATA) { 81 return false; 82 } 83 if (ltype == TRACE_TYPE_PCAPNG_META) { 84 return false; 85 } 86 if (ltype == TRACE_TYPE_ERF_META) { 87 return false; 88 } 89 90 return true; 91 } 73 92 74 93 /* … … 308 327 } 309 328 310 311 free(FORMAT_DATA->filter);329 if (FORMAT_DATA->filter != NULL) 330 trace_destroy_filter(FORMAT_DATA->filter); 312 331 313 332 if (FORMAT_DATA->per_stream) … … 709 728 libtrace_packet_t *packet) 710 729 { 730 /* Check linuxring can write this type of packet */ 731 if (!linuxring_can_write(packet)) { 732 return 0; 733 } 734 711 735 struct tpacket2_hdr *header; 712 736 struct pollfd pollset; … … 715 739 unsigned max_size; 716 740 void * off; 717 718 if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)719 return 0;720 741 721 742 max_size = FORMAT_DATA_OUT->req.tp_frame_size - -
lib/format_ndag.c
r509ee47 r6514097 335 335 default: 336 336 trace_set_err(libtrace, TRACE_ERR_OPTION_UNAVAIL, 337 "Unsupported option"); 337 "Unsupported option %d", 338 option); 338 339 return -1; 339 340 } -
lib/format_pcap.c
rd439067 r9a6bdbc 97 97 } output; 98 98 }; 99 100 static bool pcap_can_write(libtrace_packet_t *packet) { 101 /* Get the linktype */ 102 libtrace_linktype_t ltype = trace_get_link_type(packet); 103 104 if (ltype == TRACE_TYPE_PCAPNG_META 105 || ltype == TRACE_TYPE_CONTENT_INVALID 106 || ltype == TRACE_TYPE_UNKNOWN 107 || ltype == TRACE_TYPE_ERF_META 108 || ltype == TRACE_TYPE_NONDATA) { 109 110 return false; 111 } 112 113 return true; 114 } 99 115 100 116 static int pcap_init_input(libtrace_t *libtrace) { … … 521 537 { 522 538 539 /* Check pcap can write this type of packet */ 540 if (!pcap_can_write(packet)) { 541 return 0; 542 } 543 523 544 if (!libtrace) { 524 545 fprintf(stderr, "NULL trace passed into pcap_write_packet()\n"); … … 536 557 537 558 link = trace_get_packet_buffer(packet,&linktype,&remaining); 538 539 /* Silently discard RT metadata packets and packets with an540 * unknown linktype. */541 if (linktype == TRACE_TYPE_NONDATA || linktype == TRACE_TYPE_UNKNOWN || linktype == TRACE_TYPE_ERF_META || linktype == TRACE_TYPE_CONTENT_INVALID) {542 return 0;543 }544 559 545 560 /* We may have to convert this packet into a suitable PCAP packet */ -
lib/format_pcapfile.c
rd439067 r5460603 68 68 #define MAGIC2_REV 0x4d3cb2a1 69 69 70 static bool pcapfile_can_write(libtrace_packet_t *packet) { 71 /* Get the linktype */ 72 libtrace_linktype_t ltype = trace_get_link_type(packet); 73 74 if (ltype == TRACE_TYPE_PCAPNG_META 75 || ltype == TRACE_TYPE_CONTENT_INVALID 76 || ltype == TRACE_TYPE_UNKNOWN 77 || ltype == TRACE_TYPE_ERF_META 78 || ltype == TRACE_TYPE_NONDATA) { 79 80 return false; 81 } 82 83 return true; 84 } 85 70 86 static inline int header_is_backwards_magic(pcapfile_header_t *header) { 71 87 return (header->magic_number == MAGIC1_REV || header->magic_number == MAGIC2_REV); … … 175 191 if (!DATA(libtrace)) 176 192 return num; 177 193 178 194 /* We can use the PCAP magic number to determine the byte order */ 179 195 if (header_is_backwards_magic(&(DATA(libtrace)->header))) … … 371 387 packet->buffer, 372 388 sizeof(libtrace_pcapfile_pkt_hdr_t)); 389 373 390 if (err<0) { 374 391 trace_set_err(libtrace,TRACE_ERR_WANDIO_FAILED,"reading packet"); … … 387 404 bytes_to_read = swapl(libtrace,((libtrace_pcapfile_pkt_hdr_t*)packet->buffer)->caplen); 388 405 389 if (bytes_to_read >= LIBTRACE_PACKET_BUFSIZE) { 406 if (bytes_to_read >= (LIBTRACE_PACKET_BUFSIZE - 407 sizeof(libtrace_pcapfile_pkt_hdr_t))) { 390 408 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Invalid caplen in pcap header (%u) - trace may be corrupt", (uint32_t)bytes_to_read); 391 409 return -1; … … 432 450 libtrace_packet_t *packet) 433 451 { 452 453 /* Check pcapfile can write this type of packet */ 454 if (!pcapfile_can_write(packet)) { 455 return 0; 456 } 457 434 458 struct libtrace_pcapfile_pkt_hdr_t hdr; 435 459 struct timeval tv = trace_get_timeval(packet); … … 441 465 442 466 ptr = trace_get_packet_buffer(packet,&linktype,&remaining); 443 444 /* Silently discard RT metadata packets and packets with an445 * unknown linktype. */446 if (linktype == TRACE_TYPE_NONDATA || linktype == TRACE_TYPE_UNKNOWN || linktype == TRACE_TYPE_ERF_META || linktype == TRACE_TYPE_CONTENT_INVALID) {447 return 0;448 }449 467 450 468 /* If this packet cannot be converted to a pcap linktype then … … 572 590 struct timeval ts; 573 591 592 memset(&ts, 0, sizeof(struct timeval)); 593 574 594 if (!packet) { 575 595 fprintf(stderr, "NULL packet passed to pcapfile_get_timeval()\n"); … … 601 621 struct timespec ts; 602 622 623 memset(&ts, 0, sizeof(struct timespec)); 603 624 if (!packet) { 604 625 fprintf(stderr, "NULL packet passed to pcapfile_get_timespec()"); … … 655 676 "pcapfile_get_wire_length()"); 656 677 return -1; 678 } 679 680 if (packet->payload == NULL) { 681 return 0; 657 682 } 658 683 -
lib/format_pcapng.c
rd439067 r063d5dd 48 48 #define PCAPNG_CUSTOM_TYPE 0x00000BAD 49 49 #define PCAPNG_CUSTOM_NONCOPY_TYPE 0x40000BAD 50 #define PCAPNG_DECRYPTION_SECRETS_TYPE 0x0000000A 51 52 #define PCAPNG_NRB_RECORD_END 0x0000 53 #define PCAPNG_NRB_RECORD_IP4 0x0001 54 #define PCAPNG_NRB_RECORD_IP6 0x0002 55 56 #define PCAPNG_CUSTOM_OPTION_UTF8 0xBAC 57 #define PCAPNG_CUSTOM_OPTION_BIN 0xBAD 58 #define PCAPNG_CUSTOM_OPTION_UTF8_NONCOPY 0x4BAC 59 #define PCAPNG_CUSTOM_OPTION_BIN_NONCOPY 0x4BAD 60 61 #define PCAPNG_OPTION_END 0x0000 50 62 51 63 #define PACKET_IS_ENHANCED (pcapng_get_record_type(packet) == PCAPNG_ENHANCED_PACKET_TYPE) … … 54 66 55 67 #define PACKET_IS_OLD (pcapng_get_record_type(packet) == PCAPNG_OLD_PACKET_TYPE) 56 57 68 58 69 #define PCAPNG_IFOPT_TSRESOL 9 … … 133 144 typedef struct pcapng_interface_t pcapng_interface_t; 134 145 146 struct pcapng_timestamp { 147 uint32_t timehigh; 148 uint32_t timelow; 149 }; 150 135 151 struct pcapng_interface_t { 136 152 … … 160 176 uint16_t allocatedinterfaces; 161 177 uint16_t nextintid; 178 179 }; 180 181 struct pcapng_format_data_out_t { 182 iow_t *file; 183 int compress_level; 184 int compress_type; 185 int flag; 186 187 /* Section data */ 188 uint16_t sechdr_count; 189 bool byteswapped; 190 191 /* Interface data */ 192 uint16_t nextintid; 193 libtrace_linktype_t lastdlt; 162 194 }; 163 195 … … 167 199 }; 168 200 201 struct pcapng_custom_optheader { 202 uint16_t optcode; 203 uint16_t optlen; 204 uint32_t pen; 205 }; 206 struct pcapng_nrb_record { 207 uint16_t recordtype; 208 uint16_t recordlen; 209 }; 169 210 struct pcapng_peeker { 170 211 uint32_t blocktype; … … 174 215 typedef struct pcapng_peeker pcapng_hdr_t; 175 216 176 177 217 #define DATA(x) ((struct pcapng_format_data_t *)((x)->format_data)) 218 #define DATAOUT(x) ((struct pcapng_format_data_out_t*)((x)->format_data)) 219 220 static char *pcapng_parse_next_option(libtrace_t *libtrace, char **pktbuf, 221 uint16_t *code, uint16_t *length, pcapng_hdr_t *blockhdr); 222 223 static bool pcapng_can_write(libtrace_packet_t *packet) { 224 /* Get the linktype */ 225 libtrace_linktype_t ltype = trace_get_link_type(packet); 226 227 /* TODO convert erf meta to pcapng meta? */ 228 if (ltype == TRACE_TYPE_CONTENT_INVALID 229 || ltype == TRACE_TYPE_UNKNOWN 230 || ltype == TRACE_TYPE_ERF_META 231 || ltype == TRACE_TYPE_NONDATA) { 232 233 return false; 234 } 235 236 return true; 237 } 178 238 179 239 static pcapng_interface_t *lookup_interface(libtrace_t *libtrace, 180 240 uint32_t intid) { 181 241 182 183 if (intid >= DATA(libtrace)->nextintid) { 184 return NULL; 185 } 186 187 return DATA(libtrace)->interfaces[intid]; 188 242 if (intid >= DATA(libtrace)->nextintid) { 243 return NULL; 244 } 245 246 return DATA(libtrace)->interfaces[intid]; 189 247 } 190 248 191 249 static inline uint32_t pcapng_get_record_type(const libtrace_packet_t *packet) { 192 193 250 uint32_t *btype = (uint32_t *)packet->header; 194 251 195 if (DATA(packet->trace)->byteswapped) 196 return byteswap32(*btype); 252 /* only check for byteswapped if input format is pcapng */ 253 if (packet->trace->format->type == TRACE_FORMAT_PCAPNG) { 254 if (DATA(packet->trace)->byteswapped) 255 return byteswap32(*btype); 256 } 257 197 258 return *btype; 259 } 260 261 static inline uint32_t pcapng_swap32(libtrace_out_t *libtrace, uint32_t value) { 262 if (DATAOUT(libtrace)->byteswapped) { 263 return byteswap32(value); 264 } else { 265 return value; 266 } 267 } 268 static inline uint32_t pcapng_swap16(libtrace_out_t *libtrace, uint32_t value) { 269 if (DATAOUT(libtrace)->byteswapped) { 270 return byteswap16(value); 271 } else { 272 return value; 273 } 274 } 275 static inline uint32_t pcapng_get_blocklen(const libtrace_packet_t *packet) { 276 struct pcapng_peeker *hdr = (struct pcapng_peeker *)packet->buffer; 277 278 /* only check for byteswapped if input format is pcapng */ 279 if (packet->trace->format->type == TRACE_FORMAT_PCAPNG) { 280 if (DATA(packet->trace)->byteswapped) 281 return byteswap32(hdr->blocklen); 282 } 283 284 return hdr->blocklen; 285 286 } 287 288 #if 0 289 static inline uint16_t pcapng_get_customdata_len(libtrace_packet_t *packet, char *ptr) { 290 struct pcapng_custom_optheader *hdr = (struct pcapng_custom_optheader *)ptr; 291 292 if (DATA(packet->trace)->byteswapped) { 293 return byteswap16(hdr->optlen); 294 } else { 295 return hdr->optlen; 296 } 297 } 298 static inline uint16_t pcapng_get_customdata_optcode(libtrace_packet_t *packet, char *ptr) { 299 struct pcapng_custom_optheader *hdr = (struct pcapng_custom_optheader *)ptr; 300 301 if (DATA(packet->trace)->byteswapped) { 302 return byteswap16(hdr->optcode); 303 } else { 304 return hdr->optcode; 305 } 306 } 307 #endif 308 309 static inline uint16_t pcapng_get_nrb_record_type(libtrace_packet_t *packet, char *ptr) { 310 struct pcapng_nrb_record *hdr = (struct pcapng_nrb_record *)ptr; 311 if (DATA(packet->trace)->byteswapped) { 312 return byteswap16(hdr->recordtype); 313 } else { 314 return hdr->recordtype; 315 } 316 } 317 static inline uint16_t pcapng_get_nrb_record_len(libtrace_packet_t *packet, char *ptr) { 318 struct pcapng_nrb_record *hdr = (struct pcapng_nrb_record *)ptr; 319 if (DATA(packet->trace)->byteswapped) { 320 return byteswap16(hdr->recordlen); 321 } else { 322 return hdr->recordlen; 323 } 324 } 325 static uint32_t pcapng_output_options(libtrace_out_t *libtrace, libtrace_packet_t *packet, 326 char *ptr) { 327 328 struct pcapng_optheader opthdr; 329 uint16_t optcode, optlen; 330 char *optval = NULL; 331 char *bodyptr = NULL; 332 int padding; 333 void *padding_data; 334 uint32_t len = 0; 335 336 bodyptr = ptr; 337 338 while ((optval = pcapng_parse_next_option(packet->trace, &bodyptr, 339 &optcode, &optlen, (pcapng_hdr_t *) packet->buffer))) { 340 341 /* pcapng_parse_next_option byteswaps the opcode and len for us */ 342 opthdr.optcode = optcode; 343 opthdr.optlen = optlen; 344 345 /* output the header */ 346 wandio_wwrite(DATAOUT(libtrace)->file, &opthdr, sizeof(opthdr)); 347 348 /* If this is a custom option */ 349 if (optcode == PCAPNG_CUSTOM_OPTION_UTF8 || 350 optcode == PCAPNG_CUSTOM_OPTION_BIN || 351 optcode == PCAPNG_CUSTOM_OPTION_UTF8_NONCOPY || 352 optcode == PCAPNG_CUSTOM_OPTION_BIN_NONCOPY) { 353 /* flip the pen and output the option value */ 354 //uint32_t pen = byteswap32((uint32_t)*optval); 355 wandio_wwrite(DATAOUT(libtrace)->file, optval, sizeof(uint32_t)); 356 357 /* the len for custom options include pen */ 358 optval += sizeof(uint32_t); 359 optlen -= sizeof(uint32_t); 360 } 361 362 /* output the rest of the data */ 363 wandio_wwrite(DATAOUT(libtrace)->file, &optval, optlen); 364 365 /* calculate any required padding */ 366 padding = optlen % 4; 367 if (padding) { padding = 4 - padding; } 368 padding_data = calloc(1, padding); 369 /* output the padding */ 370 wandio_wwrite(DATAOUT(libtrace)->file, padding_data, padding); 371 free(padding_data); 372 373 len += sizeof(opthdr) + optlen; 374 } 375 376 return len; 377 } 378 static uint32_t pcapng_output_interface_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 379 pcapng_int_t *cur = (pcapng_int_t *)packet->header; 380 pcapng_int_t hdr; 381 char *bodyptr = NULL; 382 383 /* If the input trace is not pcapng we have no way of finding the byteordering 384 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 385 * is in the correct byte ordering just output it */ 386 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 387 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 388 uint32_t len = pcapng_get_blocklen(packet); 389 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 390 return len; 391 } 392 393 /* Byteswap the headers */ 394 hdr.blocktype = byteswap32(cur->blocktype); 395 hdr.blocklen = byteswap32(cur->blocklen); 396 hdr.linktype = byteswap16(cur->linktype); 397 hdr.reserved = byteswap16(cur->reserved); 398 hdr.snaplen = byteswap32(cur->snaplen); 399 400 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 401 /* output any options */ 402 bodyptr = (char *)packet->buffer + sizeof(hdr); 403 pcapng_output_options(libtrace, packet, bodyptr); 404 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 405 406 return hdr.blocklen; 407 } 408 static uint32_t pcapng_output_simple_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 409 pcapng_spkt_t *cur = (pcapng_spkt_t *)packet->header; 410 pcapng_spkt_t hdr; 411 uint32_t len; 412 char *bodyptr = NULL; 413 414 /* If the input trace is not pcapng we have no way of finding the byteordering 415 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 416 * is in the correct byte ordering just output it */ 417 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 418 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 419 len = pcapng_get_blocklen(packet); 420 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 421 return len; 422 } 423 424 hdr.blocktype = byteswap32(cur->blocktype); 425 hdr.blocklen = byteswap32(cur->blocklen); 426 hdr.wlen = byteswap32(cur->wlen); 427 428 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 429 430 /* output the packet payload */ 431 bodyptr = (char *)packet->buffer + sizeof(hdr); 432 len = pcapng_get_blocklen(packet) - sizeof(hdr) - sizeof(hdr.blocklen); 433 wandio_wwrite(DATAOUT(libtrace)->file, bodyptr, len); 434 435 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 436 437 return hdr.blocklen; 438 } 439 static uint32_t pcapng_output_old_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 440 pcapng_opkt_t *cur = (pcapng_opkt_t *)packet->header; 441 pcapng_opkt_t hdr; 442 uint32_t len; 443 char *bodyptr = NULL; 444 445 /* If the input trace is not pcapng we have no way of finding the byteordering 446 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 447 * is in the correct byte ordering just output it */ 448 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 449 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 450 len = pcapng_get_blocklen(packet); 451 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 452 return len; 453 } 454 455 hdr.blocktype = byteswap32(cur->blocktype); 456 hdr.blocklen = byteswap32(cur->blocklen); 457 hdr.interfaceid = byteswap16(cur->interfaceid); 458 hdr.drops = byteswap16(cur->drops); 459 hdr.timestamp_high = byteswap32(cur->timestamp_high); 460 hdr.timestamp_low = byteswap32(cur->timestamp_low); 461 hdr.caplen = byteswap32(cur->caplen); 462 hdr.wlen = byteswap32(cur->wlen); 463 464 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 465 466 /* output the packet payload */ 467 bodyptr = (char *)packet->buffer + sizeof(hdr); 468 len = pcapng_get_blocklen(packet) - sizeof(hdr) - sizeof(hdr.blocklen); 469 wandio_wwrite(DATAOUT(libtrace)->file, bodyptr, len); 470 471 /* output any options if present */ 472 pcapng_output_options(libtrace, packet, bodyptr); 473 474 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 475 476 477 return hdr.blocklen; 478 } 479 static uint32_t pcapng_output_nameresolution_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 480 pcapng_nrb_t *cur = (pcapng_nrb_t *)packet->buffer; 481 pcapng_nrb_t hdr; 482 char *bodyptr = NULL; 483 int padding; 484 void *padding_data; 485 486 /* If the input trace is not pcapng we have no way of finding the byteordering 487 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 488 * is in the correct byte ordering just output it */ 489 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 490 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 491 uint32_t len = pcapng_get_blocklen(packet); 492 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 493 return len; 494 } 495 496 hdr.blocktype = byteswap32(cur->blocktype); 497 hdr.blocklen = byteswap32(cur->blocklen); 498 499 /* output the header */ 500 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 501 bodyptr = (char *)packet->buffer + sizeof(hdr); 502 503 struct pcapng_nrb_record *nrbr = (struct pcapng_nrb_record *)bodyptr; 504 505 uint16_t record_type = pcapng_get_nrb_record_type(packet, bodyptr); 506 while (record_type != PCAPNG_NRB_RECORD_END) { 507 508 struct pcapng_nrb_record nrb; 509 510 /* recordlen contains only the length of the record value without 511 * any padding */ 512 uint16_t recordlen = pcapng_get_nrb_record_len(packet, bodyptr); 513 514 nrb.recordtype = byteswap16(nrbr->recordtype); 515 nrb.recordlen = byteswap16(nrbr->recordlen); 516 517 /* output the record header */ 518 wandio_wwrite(DATAOUT(libtrace)->file, &nrb, sizeof(nrb)); 519 bodyptr += sizeof(nrb); 520 521 /* output the record data */ 522 wandio_wwrite(DATAOUT(libtrace)->file, bodyptr, recordlen); 523 bodyptr += recordlen; 524 525 /* calculate any required padding. record also contains the 8 byte header 526 * but we dont need to subtract it because it will be removed with % 4 */ 527 padding = recordlen % 4; 528 if (padding) { padding = 4 - padding; } 529 padding_data = calloc(1, padding); 530 /* output the padding */ 531 wandio_wwrite(DATAOUT(libtrace)->file, padding_data, padding); 532 free(padding_data); 533 bodyptr += padding; 534 535 /* get the next record if it exists */ 536 nrbr = (struct pcapng_nrb_record *)bodyptr; 537 record_type = pcapng_get_nrb_record_type(packet, bodyptr); 538 } 539 540 /* output nrb record end block */ 541 struct pcapng_nrb_record nrbftr; 542 nrbftr.recordtype = PCAPNG_NRB_RECORD_END; 543 nrbftr.recordlen = 0; 544 wandio_wwrite(DATAOUT(libtrace)->file, &nrbftr, sizeof(nrbftr)); 545 bodyptr += sizeof(nrbftr); 546 547 /* output any options if present */ 548 pcapng_output_options(libtrace, packet, bodyptr); 549 550 /* and print out rest of the header */ 551 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 552 553 return hdr.blocklen; 554 } 555 static uint32_t pcapng_output_custom_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 556 pcapng_custom_t *cur = (pcapng_custom_t *)packet->buffer; 557 pcapng_custom_t hdr; 558 char *bodyptr = (char *)packet->buffer; 559 560 /* If the input trace is not pcapng we have no way of finding the byteordering 561 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 562 * is in the correct byte ordering just output it */ 563 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 564 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 565 uint32_t len = pcapng_get_blocklen(packet); 566 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 567 return len; 568 } 569 570 hdr.blocktype = byteswap32(cur->blocktype); 571 hdr.blocklen = byteswap32(cur->blocklen); 572 hdr.pen = byteswap32(cur->blocklen); 573 574 /* output the header */ 575 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 576 bodyptr += sizeof(hdr); 577 578 /* now print out any options */ 579 pcapng_output_options(libtrace, packet, bodyptr); 580 581 /* and print out rest of the header */ 582 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 583 584 return hdr.blocklen; 585 } 586 static uint32_t pcapng_output_enhanced_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 587 pcapng_epkt_t *cur = (pcapng_epkt_t *)packet->buffer; 588 pcapng_epkt_t hdr; 589 char *bodyptr = NULL; 590 uint32_t len; 591 592 /* If the input trace is not pcapng we have no way of finding the byteordering 593 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 594 * is in the correct byte ordering just output it */ 595 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 596 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 597 len = pcapng_get_blocklen(packet); 598 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 599 return len; 600 } 601 602 hdr.blocktype = byteswap32(cur->blocktype); 603 hdr.blocklen = byteswap32(cur->blocklen); 604 hdr.interfaceid = byteswap32(cur->interfaceid); 605 hdr.timestamp_high = byteswap32(cur->timestamp_high); 606 hdr.timestamp_low = byteswap32(cur->timestamp_low); 607 hdr.caplen = byteswap32(cur->caplen); 608 hdr.wlen = byteswap32(cur->wlen); 609 610 /* output beginning of header */ 611 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 612 613 /* output the packet payload */ 614 bodyptr = (char *)packet->buffer + sizeof(hdr); 615 len = pcapng_get_blocklen(packet) - sizeof(hdr) - sizeof(hdr.blocklen); 616 wandio_wwrite(DATAOUT(libtrace)->file, bodyptr, len); 617 618 /* output any options */ 619 pcapng_output_options(libtrace, packet, bodyptr); 620 621 /* output end of header */ 622 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 623 624 return hdr.blocklen; 625 } 626 static uint32_t pcapng_output_interfacestats_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 627 pcapng_stats_t *cur = (pcapng_stats_t *)packet->header; 628 pcapng_stats_t hdr; 629 char *bodyptr = NULL; 630 631 /* If the input trace is not pcapng we have no way of finding the byteordering 632 * this can occur if a packet is reconstructed with a deadtrace. Or if the packet 633 * is in the correct byte ordering just output it */ 634 if ((packet->trace->format->type != TRACE_FORMAT_PCAPNG) || 635 (DATA(packet->trace)->byteswapped == DATAOUT(libtrace)->byteswapped)) { 636 uint32_t len = pcapng_get_blocklen(packet); 637 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, len); 638 return len; 639 } 640 641 hdr.blocktype = byteswap32(cur->blocktype); 642 hdr.blocklen = byteswap32(cur->blocklen); 643 hdr.interfaceid = byteswap32(cur->interfaceid); 644 hdr.timestamp_high = byteswap32(cur->timestamp_high); 645 hdr.timestamp_low = byteswap32(cur->timestamp_low); 646 647 /* output interface stats header */ 648 wandio_wwrite(DATAOUT(libtrace)->file, &hdr, sizeof(hdr)); 649 /* output any options if present */ 650 bodyptr = (char *)packet->buffer + sizeof(hdr); 651 pcapng_output_options(libtrace, packet, bodyptr); 652 /* output rest of interface stats header */ 653 wandio_wwrite(DATAOUT(libtrace)->file, &hdr.blocklen, sizeof(hdr.blocklen)); 654 655 return hdr.blocklen; 198 656 } 199 657 … … 212 670 } 213 671 return 0; 672 } 673 674 static struct pcapng_timestamp pcapng_get_timestamp(libtrace_packet_t *packet) { 675 struct timeval tv = trace_get_timeval(packet); 676 uint64_t time = ((uint64_t)tv.tv_sec * (uint64_t)1000000) + tv.tv_usec; 677 678 struct pcapng_timestamp timestamp; 679 timestamp.timehigh = time >> 32; 680 timestamp.timelow = time & 0xFFFFFFFF; 681 682 return timestamp; 214 683 } 215 684 … … 232 701 233 702 return 0; 703 } 704 705 static int pcapng_config_output(libtrace_out_t *libtrace, trace_option_output_t option, 706 void *value) { 707 708 switch (option) { 709 case TRACE_OPTION_OUTPUT_COMPRESS: 710 DATAOUT(libtrace)->compress_level = *(int *)value; 711 return 0; 712 case TRACE_OPTION_OUTPUT_COMPRESSTYPE: 713 DATAOUT(libtrace)->compress_type = *(int *)value; 714 return 0; 715 case TRACE_OPTION_OUTPUT_FILEFLAGS: 716 DATAOUT(libtrace)->flag = *(int *)value; 717 return 0; 718 default: 719 trace_set_err_out(libtrace, TRACE_ERR_UNKNOWN_OPTION, 720 "Unknown option"); 721 return -1; 722 } 234 723 } 235 724 … … 272 761 } 273 762 763 static int pcapng_init_output(libtrace_out_t *libtrace) { 764 libtrace->format_data = malloc(sizeof(struct pcapng_format_data_out_t)); 765 766 DATAOUT(libtrace)->file = NULL; 767 DATAOUT(libtrace)->compress_level = 0; 768 DATAOUT(libtrace)->compress_type = TRACE_OPTION_COMPRESSTYPE_NONE; 769 DATAOUT(libtrace)->flag = O_CREAT|O_WRONLY; 770 771 DATAOUT(libtrace)->sechdr_count = 0; 772 DATAOUT(libtrace)->byteswapped = false; 773 774 DATAOUT(libtrace)->nextintid = 0; 775 DATAOUT(libtrace)->lastdlt = 0; 776 777 return 0; 778 } 779 274 780 static int pcapng_fin_input(libtrace_t *libtrace) { 275 781 … … 287 793 free(libtrace->format_data); 288 794 return 0; 795 } 796 797 static int pcapng_fin_output(libtrace_out_t *libtrace) { 798 if (DATAOUT(libtrace)->file) { 799 wandio_wdestroy(DATAOUT(libtrace)->file); 800 } 801 free(libtrace->format_data); 802 libtrace->format_data = NULL; 803 return 0; 289 804 } 290 805 … … 432 947 } 433 948 949 static int pcapng_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { 950 951 if (!libtrace) { 952 fprintf(stderr, "NULL trace passed into pcapng_write_packet()\n"); 953 return TRACE_ERR_NULL_TRACE; 954 } 955 if (!packet) { 956 trace_set_err_out(libtrace, TRACE_ERR_NULL_PACKET, "NULL packet passed " 957 "into pcapng_write_packet()\n"); 958 return -1; 959 } 960 961 /* Check pcapng can write this type of packet */ 962 if (!pcapng_can_write(packet)) { 963 return 0; 964 } 965 966 libtrace_linktype_t linktype = trace_get_link_type(packet); 967 968 /* If the file is not open, open it */ 969 if (!DATAOUT(libtrace)->file) { 970 DATAOUT(libtrace)->file = trace_open_file_out(libtrace, 971 DATAOUT(libtrace)->compress_type, 972 DATAOUT(libtrace)->compress_level, 973 DATAOUT(libtrace)->flag); 974 } 975 976 /* If the packet is already encapsulated in a pcapng frame just output it */ 977 switch (pcapng_get_record_type(packet)) { 978 case PCAPNG_SECTION_TYPE: { 979 /* If the section header passed in is byteswapped, everything we output 980 * till the next section header needs to be byteswapped. The next header 981 * will determine if we need to continue swapping bytes */ 982 if (DATA(packet->trace)->byteswapped) { 983 DATAOUT(libtrace)->byteswapped = true; 984 } else { 985 DATAOUT(libtrace)->byteswapped = false; 986 } 987 988 wandio_wwrite(DATAOUT(libtrace)->file, packet->buffer, 989 pcapng_get_blocklen(packet)); 990 991 DATAOUT(libtrace)->sechdr_count += 1; 992 993 return pcapng_get_blocklen(packet); 994 } 995 case PCAPNG_INTERFACE_TYPE: { 996 /* increment the interface id */ 997 DATAOUT(libtrace)->nextintid += 1; 998 999 return pcapng_output_interface_packet(libtrace, packet); 1000 } 1001 case PCAPNG_OLD_PACKET_TYPE: { 1002 return pcapng_output_old_packet(libtrace, packet); 1003 } 1004 case PCAPNG_SIMPLE_PACKET_TYPE: { 1005 if (DATAOUT(libtrace)->nextintid == 0) { 1006 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET, 1007 "Cannot output simple packet before a interface " 1008 "block has been output in pcapng_write_packet()\n"); 1009 return -1; 1010 } 1011 return pcapng_output_simple_packet(libtrace, packet); 1012 } 1013 case PCAPNG_NAME_RESOLUTION_TYPE: { 1014 return pcapng_output_nameresolution_packet(libtrace, packet); 1015 } 1016 case PCAPNG_INTERFACE_STATS_TYPE: { 1017 if (DATAOUT(libtrace)->nextintid == 0) { 1018 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET, 1019 "Cannot output a interface statistics block before a " 1020 "interface block has been output in pcapng_write_packet()\n"); 1021 return -1; 1022 } 1023 return pcapng_output_interfacestats_packet(libtrace, packet); 1024 } 1025 case PCAPNG_ENHANCED_PACKET_TYPE: { 1026 if (DATAOUT(libtrace)->nextintid == 0) { 1027 trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET, 1028 "Cannot output enhanced packet before a interface " 1029 "block has been output in pcapng_write_packet()\n"); 1030 return -1; 1031 } 1032 return pcapng_output_enhanced_packet(libtrace, packet); 1033 } 1034 case PCAPNG_CUSTOM_TYPE: { 1035 return pcapng_output_custom_packet(libtrace, packet); 1036 } 1037 case PCAPNG_DECRYPTION_SECRETS_TYPE: { 1038 return 0; 1039 } 1040 case PCAPNG_CUSTOM_NONCOPY_TYPE: { 1041 /* This custom block type is not ment to be copied */ 1042 return 0; 1043 } 1044 default: { 1045 1046 /* create section header if not already */ 1047 if (DATAOUT(libtrace)->sechdr_count == 0) { 1048 /* Create section block */ 1049 pcapng_sec_t sechdr; 1050 sechdr.blocktype = pcapng_swap32(libtrace, PCAPNG_SECTION_TYPE); 1051 sechdr.blocklen = pcapng_swap32(libtrace, 28); 1052 sechdr.ordering = pcapng_swap32(libtrace, 0x1A2B3C4D); 1053 sechdr.majorversion = pcapng_swap16(libtrace, 1); 1054 sechdr.minorversion = 0; 1055 sechdr.sectionlen = 0xFFFFFFFFFFFFFFFF; 1056 1057 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr, sizeof(sechdr)); 1058 wandio_wwrite(DATAOUT(libtrace)->file, &sechdr.blocklen, sizeof(sechdr.blocklen)); 1059 1060 DATAOUT(libtrace)->sechdr_count += 1; 1061 } 1062 1063 /* create interface header if not already or if the linktype has changed */ 1064 if (DATAOUT(libtrace)->nextintid == 0 1065 || DATAOUT(libtrace)->lastdlt != linktype) { 1066 /* Create interface block*/ 1067 pcapng_int_t inthdr; 1068 inthdr.blocktype = pcapng_swap32(libtrace, PCAPNG_INTERFACE_TYPE); 1069 inthdr.blocklen = pcapng_swap32(libtrace, 20); 1070 inthdr.linktype = pcapng_swap16(libtrace, libtrace_to_pcap_dlt(linktype)); 1071 inthdr.reserved = 0; 1072 inthdr.snaplen = 0; 1073 1074 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr, sizeof(inthdr)); 1075 wandio_wwrite(DATAOUT(libtrace)->file, &inthdr.blocklen, sizeof(inthdr.blocklen)); 1076 1077 /* increment the interface counter */ 1078 DATAOUT(libtrace)->nextintid += 1; 1079 /* update the last linktype */ 1080 DATAOUT(libtrace)->lastdlt = linktype; 1081 } 1082 1083 break; 1084 } 1085 } 1086 1087 /* If we get this far the packet is not a pcapng type so we need to encapsulate it 1088 * within a enhanced pcapng packet */ 1089 uint32_t remaining; 1090 void *link; 1091 uint32_t blocklen; 1092 uint32_t padding; 1093 uint32_t caplen; 1094 uint32_t wirelen; 1095 void *padding_data; 1096 pcapng_epkt_t epkthdr; 1097 1098 link = trace_get_packet_buffer(packet, &linktype, &remaining); 1099 1100 wirelen = trace_get_wire_length(packet); 1101 caplen = trace_get_capture_length(packet); 1102 1103 /* trace_get_wirelength includes FCS, while pcapng doesn't */ 1104 if (trace_get_link_type(packet)==TRACE_TYPE_ETH) { 1105 if (wirelen >= 4) { 1106 wirelen -= 4; 1107 } else { 1108 wirelen = 0; 1109 } 1110 } 1111 /* capture length should always be less than the wirelength */ 1112 if (caplen > wirelen) { 1113 caplen = wirelen; 1114 } 1115 1116 /* calculate padding to 32bits */ 1117 padding = caplen % 4; 1118 if (padding) { padding = 4 - padding; } 1119 padding_data = calloc(1, padding); 1120 1121 /* get pcapng_timestamp */ 1122 struct pcapng_timestamp ts = pcapng_get_timestamp(packet); 1123 1124 /* calculate the block length */ 1125 blocklen = sizeof(epkthdr) + sizeof(epkthdr.blocklen) + caplen + padding; 1126 1127 /* construct the packet */ 1128 epkthdr.blocktype = pcapng_swap32(libtrace, PCAPNG_ENHANCED_PACKET_TYPE); 1129 epkthdr.blocklen = pcapng_swap32(libtrace, blocklen); 1130 epkthdr.interfaceid = pcapng_swap32(libtrace, DATAOUT(libtrace)->nextintid-1); 1131 epkthdr.timestamp_high = pcapng_swap32(libtrace, ts.timehigh); 1132 epkthdr.timestamp_low = pcapng_swap32(libtrace, ts.timelow); 1133 epkthdr.wlen = pcapng_swap32(libtrace, wirelen); 1134 epkthdr.caplen = pcapng_swap32(libtrace, caplen); 1135 1136 /* output enhanced packet header */ 1137 wandio_wwrite(DATAOUT(libtrace)->file, &epkthdr, sizeof(epkthdr)); 1138 /* output the packet */ 1139 wandio_wwrite(DATAOUT(libtrace)->file, link, (size_t)caplen); 1140 /* output padding */ 1141 wandio_wwrite(DATAOUT(libtrace)->file, padding_data, (size_t)padding); 1142 /* output rest of the enhanced packet */ 1143 wandio_wwrite(DATAOUT(libtrace)->file, &epkthdr.blocklen, sizeof(epkthdr.blocklen)); 1144 1145 /* release padding memory */ 1146 free(padding_data); 1147 1148 return blocklen; 1149 } 1150 1151 static int pcapng_flush_output(libtrace_out_t *libtrace) { 1152 return wandio_wflush(DATAOUT(libtrace)->file); 1153 } 1154 434 1155 static int pcapng_read_section(libtrace_t *libtrace, 435 1156 libtrace_packet_t *packet, uint32_t flags) { … … 437 1158 pcapng_sec_t *sechdr; 438 1159 int err; 439 uint32_t to_read ;1160 uint32_t to_read, blocklen; 440 1161 char *bodyptr = NULL; 441 1162 … … 481 1202 return -1; 482 1203 } 483 to_read = byteswap32(sechdr->blocklen) - sizeof(pcapng_sec_t); 1204 blocklen = byteswap32(sechdr->blocklen); 1205 484 1206 } else { 485 1207 if (sechdr->majorversion != 1 && sechdr->minorversion != 0) { … … 488 1210 return -1; 489 1211 } 490 to_read = sechdr->blocklen - sizeof(pcapng_sec_t); 491 } 492 1212 blocklen = sechdr->blocklen; 1213 } 1214 1215 if (blocklen < sizeof(pcapng_sec_t)) { 1216 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 1217 "Block length in pcapng section header is invalid."); 1218 return -1; 1219 } 1220 to_read = blocklen - sizeof(pcapng_sec_t); 493 1221 /* Read all of the options etc. -- we don't need them for now, but 494 1222 * we have to skip forward to the next useful header. */ 495 1223 bodyptr = (char *) packet->buffer + sizeof(pcapng_sec_t); 1224 1225 if (to_read > LIBTRACE_PACKET_BUFSIZE) { 1226 trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 1227 "Excessively large section header contents of %u bytes, likely a corrupt trace.", to_read); 1228 return -1; 1229 } 1230 496 1231 err = pcapng_read_body(libtrace, bodyptr, to_read); 497 1232 if (err <= 0) { … … 1092 1827 } 1093 1828 1094 static libtrace_linktype_t pcapng_get_link_type(const libtrace_packet_t *packet) 1095 { 1829 static libtrace_linktype_t pcapng_get_link_type(const libtrace_packet_t *packet) { 1830 1831 if (packet->type == TRACE_RT_PCAPNG_META) { 1832 return TRACE_TYPE_PCAPNG_META; 1833 } 1096 1834 1097 1835 return pcap_linktype_to_libtrace(rt_to_pcap_linktype(packet->type)); 1098 1099 1836 } 1100 1837 … … 1112 1849 uint32_t interfaceid = 0; 1113 1850 pcapng_interface_t *interface; 1851 1852 memset(&ts, 0, sizeof(struct timespec)); 1114 1853 1115 1854 if (!packet) { … … 1436 2175 pcapng_start_input, /* start_input */ 1437 2176 NULL, /* pause_input */ 1438 NULL,/* init_output */1439 NULL,/* config_output */2177 pcapng_init_output, /* init_output */ 2178 pcapng_config_output, /* config_output */ 1440 2179 NULL, /* start_output */ 1441 2180 pcapng_fin_input, /* fin_input */ 1442 NULL,/* fin_output */2181 pcapng_fin_output, /* fin_output */ 1443 2182 pcapng_read_packet, /* read_packet */ 1444 2183 pcapng_prepare_packet, /* prepare_packet */ 1445 2184 NULL, /* fin_packet */ 1446 NULL,/* write_packet */1447 NULL,/* flush_output */2185 pcapng_write_packet, /* write_packet */ 2186 pcapng_flush_output, /* flush_output */ 1448 2187 pcapng_get_link_type, /* get_link_type */ 1449 2188 pcapng_get_direction, /* get_direction */ … … 1474 2213 register_format(&pcapng); 1475 2214 } 1476 -
lib/libtrace.h.in
rdb919d5 rc876f29 414 414 TRACE_TYPE_OPENBSD_LOOP = 20, /**< OpenBSD loopback */ 415 415 TRACE_TYPE_ERF_META = 21, /**< ERF Provenance metadata record */ 416 TRACE_TYPE_ETSILI = 22 /**< ETSI Lawful Intercept */ 416 TRACE_TYPE_ETSILI = 22, /**< ETSI Lawful Intercept */ 417 TRACE_TYPE_PCAPNG_META = 23, /** PCAPNG meta packet */ 417 418 } libtrace_linktype_t; 418 419 -
lib/linktypes.c
r2193905 r49f8ceb 110 110 case TRACE_TYPE_ETSILI: 111 111 break; 112 case TRACE_TYPE_PCAPNG_META: 112 113 case TRACE_TYPE_UNKNOWN: 113 114 case TRACE_TYPE_CONTENT_INVALID: … … 212 213 case TRACE_TYPE_OPENBSD_LOOP: 213 214 case TRACE_TYPE_ETSILI: 215 case TRACE_TYPE_PCAPNG_META: 214 216 case TRACE_TYPE_UNKNOWN: 215 217 case TRACE_TYPE_CONTENT_INVALID: -
lib/protocols.h
ree6e802 rbe1b03a 24 24 * 25 25 */ 26 27 #ifndef LIBTRACE_PROTOCOLS_H_ 28 #define LIBTRACE_PROTOCOLS_H_ 26 29 27 30 /** @file … … 81 84 }; 82 85 83 86 #endif -
lib/protocols_l2.c
r692bf9c rc876f29 690 690 * calling trace_get_packet_buffer more than once like we used to. 691 691 */ 692 693 692 meta = trace_get_packet_buffer(packet, linktype, remaining); 693 if (meta == NULL) { 694 return NULL; 695 } 694 696 695 697 /* If there are no meta-data headers, we just return the start of the … … 719 721 case TRACE_TYPE_PFLOG: 720 722 case TRACE_TYPE_ERF_META: 723 case TRACE_TYPE_PCAPNG_META: 721 724 case TRACE_TYPE_ETSILI: 722 725 break; … … 757 760 case TRACE_TYPE_PFLOG: 758 761 case TRACE_TYPE_ERF_META: 762 case TRACE_TYPE_PCAPNG_META: 759 763 case TRACE_TYPE_ETSILI: 760 764 break; … … 808 812 return NULL; 809 813 } 810 814 815 if (link == NULL) { 816 return NULL; 817 } 818 811 819 switch(linktype) { 812 820 /* Packet Metadata headers, not layer2 headers */ … … 827 835 case TRACE_TYPE_METADATA: 828 836 case TRACE_TYPE_NONDATA: 837 case TRACE_TYPE_PCAPNG_META: 829 838 case TRACE_TYPE_ERF_META: 830 839 case TRACE_TYPE_CONTENT_INVALID: … … 837 846 return trace_get_payload_from_ethernet(link,ethertype,remaining); 838 847 case TRACE_TYPE_NONE: 848 if (*remaining == 0) { 849 return NULL; 850 } 851 839 852 if ((*(char*)link&0xF0) == 0x40) 840 853 *ethertype=TRACE_ETHERTYPE_IP; /* IPv4 */ 841 854 else if ((*(char*)link&0xF0) == 0x60) 842 855 *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */ 856 else 857 return NULL; /* No idea */ 843 858 return link; /* I love the simplicity */ 844 859 case TRACE_TYPE_PPP: … … 865 880 866 881 case TRACE_TYPE_OPENBSD_LOOP: 882 if (*remaining <= 4) { 883 return NULL; 884 } 867 885 link = link + 4; /* Loopback header is 4 bytes */ 868 886 if ((*(char*)link&0xF0) == 0x40) … … 870 888 else if ((*(char*)link&0xF0) == 0x60) 871 889 *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */ 890 else 891 return NULL; 872 892 return link; /* I love the simplicity */ 873 893 … … 937 957 case TRACE_TYPE_OPENBSD_LOOP: 938 958 case TRACE_TYPE_ERF_META: 959 case TRACE_TYPE_PCAPNG_META: 939 960 case TRACE_TYPE_UNKNOWN: 940 961 case TRACE_TYPE_CONTENT_INVALID: … … 993 1014 case TRACE_TYPE_OPENBSD_LOOP: 994 1015 case TRACE_TYPE_ERF_META: 1016 case TRACE_TYPE_PCAPNG_META: 995 1017 case TRACE_TYPE_UNKNOWN: 996 1018 case TRACE_TYPE_CONTENT_INVALID: -
lib/protocols_pktmeta.c
r2193905 r49f8ceb 191 191 case TRACE_TYPE_OPENBSD_LOOP: 192 192 case TRACE_TYPE_UNKNOWN: 193 case TRACE_TYPE_PCAPNG_META: 193 194 case TRACE_TYPE_CONTENT_INVALID: 194 195 return NULL; … … 249 250 return nexthdr; 250 251 252 case TRACE_TYPE_PCAPNG_META: 251 253 case TRACE_TYPE_HDLC_POS: 252 254 case TRACE_TYPE_ETH: -
lib/trace.c
rd439067 rd0941cc 1431 1431 DLLEXPORT size_t trace_get_wire_length(const libtrace_packet_t *packet){ 1432 1432 1433 size_t wiresub = 0; 1434 1433 1435 if (packet->which_trace_start != packet->trace->startcount) { 1434 1436 return ~0U; … … 1442 1444 } 1443 1445 1444 if (!(packet->cached.wire_length < LIBTRACE_PACKET_BUFSIZE)) { 1445 fprintf(stderr, "Wire length is greater than the buffer size in trace_get_wire_length()\n"); 1446 return 0; 1446 if (packet->type >= TRACE_RT_DATA_DLT && packet->type <= 1447 TRACE_RT_DATA_DLT_END) { 1448 1449 /* pcap wire lengths in libtrace include an extra four bytes 1450 * for the FCS (to be consistent with other formats that do 1451 * capture the FCS), but these bytes don't actually exist on 1452 * the wire. Therefore, we shouldn't get upset if our "wire" 1453 * length exceeds the max buffer size by four bytes or less. 1454 */ 1455 if (packet->cached.wire_length >= 4) { 1456 wiresub = 4; 1457 } else { 1458 wiresub = packet->cached.wire_length; 1459 } 1460 } else { 1461 wiresub = 0; 1462 } 1463 1464 if (!(packet->cached.wire_length - wiresub < LIBTRACE_PACKET_BUFSIZE)) { 1465 fprintf(stderr, "Wire length %zu exceeds expected maximum packet size of %d -- packet is likely corrupt.\n", 1466 packet->cached.wire_length - wiresub, 1467 LIBTRACE_PACKET_BUFSIZE); 1468 1447 1469 /* should we be returning ~OU here? */ 1448 1470 } … … 1554 1576 #else 1555 1577 struct libtrace_filter_t *filter = (struct libtrace_filter_t *) 1556 malloc(sizeof(struct libtrace_filter_t));1578 calloc(1, sizeof(struct libtrace_filter_t)); 1557 1579 filter->filter.bf_insns = (struct bpf_insn *) 1558 1580 malloc(sizeof(struct bpf_insn) * bf_len); … … 1578 1600 #ifdef HAVE_BPF 1579 1601 libtrace_filter_t *filter = (libtrace_filter_t*) 1580 malloc(sizeof(libtrace_filter_t));1602 calloc(1, sizeof(libtrace_filter_t)); 1581 1603 filter->filterstring = strdup(filterstring); 1582 1604 filter->jitfilter = NULL; … … 1718 1740 linktype = trace_get_link_type(packet); 1719 1741 1720 if (linktype == TRACE_TYPE_NONDATA || linktype == TRACE_TYPE_ERF_META) 1742 if (linktype == TRACE_TYPE_NONDATA || linktype == TRACE_TYPE_ERF_META 1743 || linktype == TRACE_TYPE_PCAPNG_META) 1721 1744 return 1; 1722 1745 -
lib/trace_parallel.c
r9c46b65 r6d2a120 2277 2277 2278 2278 if (ret == -1) { 2279 libtrace_err_t err UNUSED; 2280 2279 2281 /* We have to deal with this ourself */ 2282 /* If we succeed, clear any error state otherwise our caller 2283 * might assume an error occurred, even though we've resolved 2284 * the issue ourselves. 2285 */ 2280 2286 if (!hasher) { 2281 2287 switch (type) … … 2283 2289 case HASHER_CUSTOM: 2284 2290 case HASHER_BALANCE: 2291 err = trace_get_err(trace); 2285 2292 return 0; 2286 2293 case HASHER_BIDIRECTIONAL: … … 2288 2295 trace->hasher_data = calloc(1, sizeof(toeplitz_conf_t)); 2289 2296 toeplitz_init_config(trace->hasher_data, 1); 2297 err = trace_get_err(trace); 2290 2298 return 0; 2291 2299 case HASHER_UNIDIRECTIONAL: … … 2293 2301 trace->hasher_data = calloc(1, sizeof(toeplitz_conf_t)); 2294 2302 toeplitz_init_config(trace->hasher_data, 0); 2303 err = trace_get_err(trace); 2295 2304 return 0; 2296 2305 }
Note: See TracChangeset
for help on using the changeset viewer.