struct sect *sections_init(struct sect **sects) { *sects = NULL; section_create(sects, ".text", SECT_XLATE); section_create(sects, ".rodata", SECT_RAW); section_create(sects, ".data", SECT_RAW); section_create(sects, ".bss", SECT_ZERO); section_create(sects, ".end", SECT_RAW); return section_get(*sects, ".text"); }
section section_create_by_copy(section sec) { section newsec; newsec = section_create(sec->name); section_write(newsec, sec->size, sec->data); return newsec; }
static int digest_times(pcapreport_ctx_t *ctx, pcapreport_stream_t * const st, const pcaprec_hdr_t *pcap_pkt_hdr, const ethernet_packet_t *epkt, const ipv4_header_t *ipv4_header, const ipv4_udp_header_t *udp_header, const byte *data, const uint32_t len) { int rv; const uint64_t ts_byte_start = st->ts_bytes; if (st->ts_r == NULL) { rv = build_TS_reader_with_fns(st, digest_times_read, digest_times_seek, &st->ts_r); if (rv) { print_err( "### pcapreport: Cannot create ts reader.\n"); return 1; } } // Add all our data to the pool. { unsigned int pkts = len / 188; unsigned int pktlen = pkts * 188; if (pktlen != len) ++st->pkts_overlength; st->tmp_buf = (byte *)realloc(st->tmp_buf, st->tmp_len + pktlen); memcpy(&st->tmp_buf[st->tmp_len], data, pktlen); st->tmp_len += pktlen; st->ts_bytes += pktlen; } // Now read out all the ts packets we can. while (1) { byte *pkt; int rv; rv = read_next_TS_packet(st->ts_r, &pkt); if (rv == EOF) { // Got to EOF - return for more data return 0; } // Right. Split it .. { const uint64_t t_pcr = pkt_time(pcap_pkt_hdr); uint32_t pid; int pusi; byte *adapt; int adapt_len; byte *payload; int payload_len; rv = split_TS_packet(pkt, &pid, &pusi, &adapt, &adapt_len, &payload, &payload_len); if (rv) { fprint_msg(">%d> WARNING: TS packet %d [ packet %d @ %d.%d s ] cannot be split.\n", st->stream_no, st->ts_counter, ctx->pkt_counter, pcap_pkt_hdr->ts_sec, pcap_pkt_hdr->ts_usec); } else { //int cc; // PCR ? if (adapt && adapt_len) { int has_pcr; uint64_t pcr; int64_t pcr_time_offset; get_PCR_from_adaptation_field(adapt, adapt_len, &has_pcr, &pcr); if (has_pcr) { int64_t skew; if (ctx->time_report) { fprint_msg(">%d> Found PCR %lld at %d.%d s \n", st->stream_no, pcr, pcap_pkt_hdr->ts_sec, pcap_pkt_hdr->ts_usec); } if (st->pcr_pid == 0) st->pcr_pid = pid; if (pid != st->pcr_pid) { // *** If this happens often then fix to track each Pid if (!st->multiple_pcr_pids) { fprint_msg("!%d! Multiple pids detected: pids: %d,%d,...\n", st->stream_no, st->pcr_pid, pid); } st->multiple_pcr_pids = TRUE; } else { // PCR pops out in 27MHz units. Let's do all our comparisons // in 90kHz. pcr /= 300; // fprint_msg("pcr = %lld t_pcr = %lld diff = %lld\n", // pcr, t_pcr, t_pcr - pcr); pcr_time_offset = ((int64_t)t_pcr - (int64_t)pcr); skew = st->section_last == NULL ? 0LL : pcr_time_offset - (st->section_last->time_start - st->section_last->pcr_start); if (st->section_last == NULL || skew > st->skew_discontinuity_threshold || skew < -st->skew_discontinuity_threshold) { pcapreport_section_t * const tsect = section_create(st); if (tsect->section_no != 0) { fprint_msg(">%d> Skew discontinuity! Skew = %lld (> %lld) at" " ts = %d network = %d (PCR %lld Time %d.%d)\n", st->stream_no, skew, st->skew_discontinuity_threshold, st->ts_counter, ctx->pkt_counter, pcr, pcap_pkt_hdr->ts_sec, pcap_pkt_hdr->ts_usec); } tsect->pkt_final = tsect->pkt_start = ctx->pkt_counter; tsect->pcr_last = tsect->pcr_start = pcr; tsect->time_last = tsect->time_start = t_pcr; tsect->ts_byte_start = tsect->ts_byte_final = ts_byte_start; jitter_clear(&st->jitter); st->last_time_offset = 0; } else { pcapreport_section_t * const tsect = st->section_last; // Extract jitter over up to the last 10s. skew will be within // an int by now unsigned int cur_jitter = jitter_add(&st->jitter, (int)skew, (uint32_t)(t_pcr & 0xffffffffU), 90000 * 10); if (tsect->jitter_max < cur_jitter) tsect->jitter_max = cur_jitter; if (ctx->time_report) { int64_t rel_tim = t_pcr - tsect->time_start; // 90kHz double skew_rate = (double)skew / ((double)((double)rel_tim / (60*90000))); fprint_msg(">%d> [ts %d net %d ] PCR %lld Time %d.%d [rel %d.%d] - skew = %lld (delta = %lld, rate = %.4g PTS/min) - jitter=%u\n", st->stream_no, st->ts_counter, ctx->pkt_counter, pcr, pcap_pkt_hdr->ts_sec, pcap_pkt_hdr->ts_usec, (int)(rel_tim / (int64_t)1000000), (int)rel_tim%1000000, skew, pcr_time_offset - st->last_time_offset, skew_rate, cur_jitter); } if (st->csv_name != NULL) // We should be outputting to file { if (st->csv_file == NULL) { if ((st->csv_file = fopen(st->csv_name, "wt")) == NULL) { fprint_err("### pcapreport: Cannot open %s .\n", st->csv_name); exit(1); } fprintf(st->csv_file, "\"PKT\",\"Time\",\"PCR\",\"Skew\",\"Jitter\"\n"); } fprintf(st->csv_file, "%d,%llu,%llu,%lld,%u\n", ctx->pkt_counter, t_pcr - ctx->time_start, pcr, skew, cur_jitter); } // Remember where we are for posterity tsect->pcr_last = pcr; tsect->time_last = t_pcr; st->last_time_offset = pcr_time_offset; } } } } } { pcapreport_section_t * const tsect = st->section_last; if (tsect != NULL) { tsect->time_final = t_pcr; tsect->ts_byte_final = st->ts_bytes; tsect->pkt_final = ctx->pkt_counter; } } ++st->ts_counter; } } }
section_list coff_read(char *buf) { section_list seclist; section sec; struct coff_header *header = (struct coff_header *)buf; struct coff_optional_header *ohdr; struct coff_section_header *shdr; char name[sizeof(shdr->name) + 1]; int i, num; short sflags; long lflags; if (b16r(&header->magic) == 0x8301) { printf("This is COFF file.\n"); } else { printf("This is not COFF file.\n"); return NULL; } seclist = section_list_create(); printf("\nCOFF header information.\n"); printf("flags:"); sflags = b16r(&header->flags); if (sflags & COFF_HDR_FLAG_REL) { printf(" REL"); section_list_set_type(seclist, SECTION_LIST_TYPE_RELOCATE); } if (sflags & COFF_HDR_FLAG_EXEC) { printf(" EXEC"); section_list_set_type(seclist, SECTION_LIST_TYPE_EXEC); } if (sflags & COFF_HDR_FLAG_NOLNNUM) { printf(" NOLNNUM"); } if (sflags & COFF_HDR_FLAG_NOSYM) { printf(" NOSYM"); } printf("\n"); printf("\nOptional header information.\n"); ohdr = (struct coff_optional_header *) ((char *)header + sizeof(struct coff_header)); printf("magic : %s\n", v2ss(b16r(&ohdr->magic))); printf("version : %s\n", v2ss(b16r(&ohdr->version))); printf("text size : %s\n", v2sl(b32r(&ohdr->text_size))); printf("data size : %s\n", v2sl(b32r(&ohdr->data_size))); printf("BSS size : %s\n", v2sl(b32r(&ohdr->bss_size))); printf("entry point : %s\n", v2sl(b32r(&ohdr->entry_point))); printf("text offset : %s\n", v2sl(b32r(&ohdr->text_offset))); printf("data offset : %s\n", v2sl(b32r(&ohdr->data_offset))); section_list_set_entry_point(seclist, b32r(&ohdr->entry_point)); printf("\nSection header information.\n"); num = b16r(&header->section_num); for (i = 0; i < num; i++) { shdr = (struct coff_section_header *) ((char *)header + sizeof(struct coff_header) + b16r(&header->optional_header_size) + sizeof(struct coff_section_header) * i); strncpy(name, shdr->name, sizeof(name)); sec = section_create(name); section_list_insert(seclist, NULL, sec); printf("\n"); printf("%s\n", name); printf("paddr :0x%08lx ", b32r(&shdr->physical_addr)); printf("vaddr :0x%08lx ", b32r(&shdr->virtual_addr)); printf("size :0x%08lx ", b32r(&shdr->size)); printf("offset :0x%08lx\n", b32r(&shdr->offset)); printf("reloc :0x%08lx ", b32r(&shdr->relocation)); printf("lnnum :0x%08lx ", b32r(&shdr->line_number)); printf("nreloc :0x%04x ", b16r(&shdr->relocation_num)); printf("nlnnum :0x%04x\n", b16r(&shdr->line_number_num)); section_set_physical_addr(sec, b32r(&shdr->physical_addr)); section_set_virtual_addr(sec, b32r(&shdr->virtual_addr)); lflags = b32r(&shdr->flags); printf("flags :0x%08lx (", lflags); section_set_type(sec, SECTION_TYPE_OTHER); if (lflags & COFF_SHDR_FLAG_TEXT) { printf(" TEXT"); if (!strcmp(name, ".rodata")) section_set_type(sec, SECTION_TYPE_RODATA); else section_set_type(sec, SECTION_TYPE_TEXT); } if (lflags & COFF_SHDR_FLAG_DATA) { printf(" DATA"); section_set_type(sec, SECTION_TYPE_DATA); } if (lflags & COFF_SHDR_FLAG_BSS) { printf(" BSS"); section_set_type(sec, SECTION_TYPE_BSS); } printf(" )\n"); section_set_memory_size(sec, b32r(&shdr->size)); if (b32r(&shdr->offset)) { section_write(sec, b32r(&shdr->size), ((char *)header + b32r(&shdr->offset))); section_set_file_size(sec, section_get_size(sec)); } } return seclist; }