static void enter_mode_read_pcap(struct mode *mode) { int ret, fd; struct pcap_pkthdr phdr; struct sock_fprog bpf_ops; struct tx_stats stats; struct frame_map fm; uint8_t *out; size_t out_len; if (!pcap_ops[mode->pcap]) panic("pcap group not supported!\n"); fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); ret = pcap_ops[mode->pcap]->pull_file_header(fd); if (ret) panic("error reading pcap header!\n"); if (pcap_ops[mode->pcap]->prepare_reading_pcap) { ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd); if (ret) panic("error prepare reading pcap!\n"); } memset(&fm, 0, sizeof(fm)); memset(&bpf_ops, 0, sizeof(bpf_ops)); memset(&stats, 0, sizeof(stats)); bpf_parse_rules(mode->filter, &bpf_ops); dissector_init_all(mode->print_mode); out_len = device_mtu("lo"); out = xmalloc_aligned(out_len, 64); printf("BPF:\n"); bpf_dump_all(&bpf_ops); printf("MD: RD %s\n\n", pcap_ops[mode->pcap]->name); while (likely(sigint == 0)) { do { ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr, out, out_len); if (unlikely(ret <= 0)) goto out; } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len)); pcap_pkthdr_to_tpacket_hdr(&phdr, &fm.tp_h); stats.tx_bytes += fm.tp_h.tp_len;; stats.tx_packets++; show_frame_hdr(&fm, mode->print_mode, RING_MODE_EGRESS); dissector_entry_point(out, fm.tp_h.tp_snaplen, mode->link_type); if (frame_cnt_max != 0 && stats.tx_packets >= frame_cnt_max) { sigint = 1; break; } } out: fflush(stdout); printf("\n"); printf("\r%12lu frames outgoing\n", stats.tx_packets); printf("\r%12lu bytes outgoing\n", stats.tx_bytes); xfree(out); dissector_cleanup_all(); if (pcap_ops[mode->pcap]->prepare_close_pcap) pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ); close(fd); }
static void read_pcap(struct ctx *ctx) { __label__ out; uint8_t *out; int ret, fd, fdo = 0; unsigned long trunced = 0; size_t out_len; pcap_pkthdr_t phdr; struct sock_fprog bpf_ops; struct frame_map fm; struct timeval start, end, diff; struct sockaddr_ll sll; bug_on(!__pcap_io); if (!strncmp("-", ctx->device_in, strlen("-"))) { fd = dup_or_die(fileno(stdin)); close(fileno(stdin)); if (ctx->pcap == PCAP_OPS_MM) ctx->pcap = PCAP_OPS_SG; } else { fd = open_or_die(ctx->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); } if (__pcap_io->init_once_pcap) __pcap_io->init_once_pcap(); ret = __pcap_io->pull_fhdr_pcap(fd, &ctx->magic, &ctx->link_type); if (ret) panic("Error reading pcap header!\n"); if (__pcap_io->prepare_access_pcap) { ret = __pcap_io->prepare_access_pcap(fd, PCAP_MODE_RD, ctx->jumbo); if (ret) panic("Error prepare reading pcap!\n"); } fmemset(&fm, 0, sizeof(fm)); fmemset(&bpf_ops, 0, sizeof(bpf_ops)); bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type); if (ctx->dump_bpf) bpf_dump_all(&bpf_ops); dissector_init_all(ctx->print_mode); out_len = round_up(1024 * 1024, PAGE_SIZE); out = xmalloc_aligned(out_len, CO_CACHE_LINE_SIZE); if (ctx->device_out) { if (!strncmp("-", ctx->device_out, strlen("-"))) { fdo = dup_or_die(fileno(stdout)); close(fileno(stdout)); } else { fdo = open_or_die_m(ctx->device_out, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, DEFFILEMODE); } } drop_privileges(ctx->enforce, ctx->uid, ctx->gid); printf("Running! Hang up with ^C!\n\n"); fflush(stdout); bug_on(gettimeofday(&start, NULL)); while (likely(sigint == 0)) { do { ret = __pcap_io->read_pcap(fd, &phdr, ctx->magic, out, out_len); if (unlikely(ret < 0)) goto out; if (unlikely(pcap_get_length(&phdr, ctx->magic) == 0)) { trunced++; continue; } if (unlikely(pcap_get_length(&phdr, ctx->magic) > out_len)) { pcap_set_length(&phdr, ctx->magic, out_len); trunced++; } } while (ctx->filter && !bpf_run_filter(&bpf_ops, out, pcap_get_length(&phdr, ctx->magic))); pcap_pkthdr_to_tpacket_hdr(&phdr, ctx->magic, &fm.tp_h, &sll); ctx->tx_bytes += fm.tp_h.tp_len; ctx->tx_packets++; show_frame_hdr(&fm, ctx->print_mode); dissector_entry_point(out, fm.tp_h.tp_snaplen, ctx->link_type, ctx->print_mode); if (ctx->device_out) translate_pcap_to_txf(fdo, out, fm.tp_h.tp_snaplen); if (frame_count_max != 0) { if (ctx->tx_packets >= frame_count_max) { sigint = 1; break; } } } out: bug_on(gettimeofday(&end, NULL)); timersub(&end, &start, &diff); bpf_release(&bpf_ops); dissector_cleanup_all(); if (__pcap_io->prepare_close_pcap) __pcap_io->prepare_close_pcap(fd, PCAP_MODE_RD); xfree(out); fflush(stdout); printf("\n"); printf("\r%12lu packets outgoing\n", ctx->tx_packets); printf("\r%12lu packets truncated in file\n", trunced); printf("\r%12lu bytes outgoing\n", ctx->tx_bytes); printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); if (!strncmp("-", ctx->device_in, strlen("-"))) dup2(fd, fileno(stdin)); close(fd); if (ctx->device_out) { if (!strncmp("-", ctx->device_out, strlen("-"))) dup2(fdo, fileno(stdout)); close(fdo); } }
static void enter_mode_pcap_to_tx(struct mode *mode) { int irq, ifindex, fd = 0, ret; unsigned int size, it = 0; struct ring tx_ring; struct frame_map *hdr; struct sock_fprog bpf_ops; struct tx_stats stats; uint8_t *out = NULL; if (!device_up_and_running(mode->device_out)) panic("Device not up and running!\n"); set_memcpy(); tx_sock = pf_socket(); if (!pcap_ops[mode->pcap]) panic("pcap group not supported!\n"); fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); ret = pcap_ops[mode->pcap]->pull_file_header(fd); if (ret) panic("error reading pcap header!\n"); if (pcap_ops[mode->pcap]->prepare_reading_pcap) { ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd); if (ret) panic("error prepare reading pcap!\n"); } memset(&tx_ring, 0, sizeof(tx_ring)); memset(&bpf_ops, 0, sizeof(bpf_ops)); memset(&stats, 0, sizeof(stats)); ifindex = device_ifindex(mode->device_out); size = ring_size(mode->device_out, mode->reserve_size); bpf_parse_rules(mode->filter, &bpf_ops); set_packet_loss_discard(tx_sock); setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support); create_tx_ring(tx_sock, &tx_ring); mmap_tx_ring(tx_sock, &tx_ring); alloc_tx_ring_frames(&tx_ring); bind_tx_ring(tx_sock, &tx_ring, ifindex); dissector_init_all(mode->print_mode); if (mode->cpu >= 0 && ifindex > 0) { irq = device_irq_number(mode->device_out); device_bind_irq_to_cpu(mode->cpu, irq); printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq, mode->cpu); } if (mode->kpull) interval = mode->kpull; itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = interval; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = interval; setitimer(ITIMER_REAL, &itimer, NULL); printf("BPF:\n"); bpf_dump_all(&bpf_ops); printf("MD: TX %luus %s\n\n", interval, pcap_ops[mode->pcap]->name); while (likely(sigint == 0)) { while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) { struct pcap_pkthdr phdr; hdr = tx_ring.frames[it].iov_base; /* Kernel assumes: data = ph.raw + po->tp_hdrlen - * sizeof(struct sockaddr_ll); */ out = ((uint8_t *) hdr) + TPACKET_HDRLEN - sizeof(struct sockaddr_ll); do { ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr, out, ring_frame_size(&tx_ring)); if (unlikely(ret <= 0)) goto out; } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len)); pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h); stats.tx_bytes += hdr->tp_h.tp_len;; stats.tx_packets++; show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS); dissector_entry_point(out, hdr->tp_h.tp_snaplen, mode->link_type); kernel_may_pull_from_tx(&hdr->tp_h); next_slot(&it, &tx_ring); if (unlikely(sigint == 1)) break; if (frame_cnt_max != 0 && stats.tx_packets >= frame_cnt_max) { sigint = 1; break; } } } out: fflush(stdout); printf("\n"); printf("\r%12lu frames outgoing\n", stats.tx_packets); printf("\r%12lu bytes outgoing\n", stats.tx_bytes); dissector_cleanup_all(); destroy_tx_ring(tx_sock, &tx_ring); close(tx_sock); if (pcap_ops[mode->pcap]->prepare_close_pcap) pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ); close(fd); }
static void pcap_to_xmit(struct ctx *ctx) { __label__ out; uint8_t *out = NULL; int irq, ifindex, fd = 0, ret; unsigned int size, it = 0; unsigned long trunced = 0; struct ring tx_ring; struct frame_map *hdr; struct sock_fprog bpf_ops; struct timeval start, end, diff; pcap_pkthdr_t phdr; if (!device_up_and_running(ctx->device_out) && !ctx->rfraw) panic("Device not up and running!\n"); bug_on(!__pcap_io); tx_sock = pf_socket(); if (!strncmp("-", ctx->device_in, strlen("-"))) { fd = dup_or_die(fileno(stdin)); close(fileno(stdin)); if (ctx->pcap == PCAP_OPS_MM) ctx->pcap = PCAP_OPS_SG; } else { fd = open_or_die(ctx->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); } if (__pcap_io->init_once_pcap) __pcap_io->init_once_pcap(); ret = __pcap_io->pull_fhdr_pcap(fd, &ctx->magic, &ctx->link_type); if (ret) panic("Error reading pcap header!\n"); if (__pcap_io->prepare_access_pcap) { ret = __pcap_io->prepare_access_pcap(fd, PCAP_MODE_RD, ctx->jumbo); if (ret) panic("Error prepare reading pcap!\n"); } fmemset(&tx_ring, 0, sizeof(tx_ring)); fmemset(&bpf_ops, 0, sizeof(bpf_ops)); if (ctx->rfraw) { ctx->device_trans = xstrdup(ctx->device_out); xfree(ctx->device_out); enter_rfmon_mac80211(ctx->device_trans, &ctx->device_out); if (ctx->link_type != LINKTYPE_IEEE802_11) panic("Wrong linktype of pcap!\n"); } ifindex = device_ifindex(ctx->device_out); size = ring_size(ctx->device_out, ctx->reserve_size); bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type); if (ctx->dump_bpf) bpf_dump_all(&bpf_ops); set_packet_loss_discard(tx_sock); setup_tx_ring_layout(tx_sock, &tx_ring, size, ctx->jumbo); create_tx_ring(tx_sock, &tx_ring, ctx->verbose); mmap_tx_ring(tx_sock, &tx_ring); alloc_tx_ring_frames(tx_sock, &tx_ring); bind_tx_ring(tx_sock, &tx_ring, ifindex); dissector_init_all(ctx->print_mode); if (ctx->cpu >= 0 && ifindex > 0) { irq = device_irq_number(ctx->device_out); device_set_irq_affinity(irq, ctx->cpu); if (ctx->verbose) printf("IRQ: %s:%d > CPU%d\n", ctx->device_out, irq, ctx->cpu); } if (ctx->kpull) interval = ctx->kpull; set_itimer_interval_value(&itimer, 0, interval); setitimer(ITIMER_REAL, &itimer, NULL); drop_privileges(ctx->enforce, ctx->uid, ctx->gid); printf("Running! Hang up with ^C!\n\n"); fflush(stdout); bug_on(gettimeofday(&start, NULL)); while (likely(sigint == 0)) { while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) { hdr = tx_ring.frames[it].iov_base; out = ((uint8_t *) hdr) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll); do { ret = __pcap_io->read_pcap(fd, &phdr, ctx->magic, out, ring_frame_size(&tx_ring)); if (unlikely(ret <= 0)) goto out; if (ring_frame_size(&tx_ring) < pcap_get_length(&phdr, ctx->magic)) { pcap_set_length(&phdr, ctx->magic, ring_frame_size(&tx_ring)); trunced++; } } while (ctx->filter && !bpf_run_filter(&bpf_ops, out, pcap_get_length(&phdr, ctx->magic))); pcap_pkthdr_to_tpacket_hdr(&phdr, ctx->magic, &hdr->tp_h, &hdr->s_ll); ctx->tx_bytes += hdr->tp_h.tp_len;; ctx->tx_packets++; show_frame_hdr(hdr, ctx->print_mode); dissector_entry_point(out, hdr->tp_h.tp_snaplen, ctx->link_type, ctx->print_mode); kernel_may_pull_from_tx(&hdr->tp_h); it++; if (it >= tx_ring.layout.tp_frame_nr) it = 0; if (unlikely(sigint == 1)) break; if (frame_count_max != 0) { if (ctx->tx_packets >= frame_count_max) { sigint = 1; break; } } } } out: bug_on(gettimeofday(&end, NULL)); timersub(&end, &start, &diff); timer_purge(); bpf_release(&bpf_ops); dissector_cleanup_all(); destroy_tx_ring(tx_sock, &tx_ring); if (ctx->rfraw) leave_rfmon_mac80211(ctx->device_trans, ctx->device_out); if (__pcap_io->prepare_close_pcap) __pcap_io->prepare_close_pcap(fd, PCAP_MODE_RD); if (!strncmp("-", ctx->device_in, strlen("-"))) dup2(fd, fileno(stdin)); close(fd); close(tx_sock); fflush(stdout); printf("\n"); printf("\r%12lu packets outgoing\n", ctx->tx_packets); printf("\r%12lu packets truncated in file\n", trunced); printf("\r%12lu bytes outgoing\n", ctx->tx_bytes); printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); }
static void read_pcap(struct ctx *ctx) { uint8_t *out; int ret, fd, fdo = 0; unsigned long trunced = 0; size_t out_len; pcap_pkthdr_t phdr; struct sock_fprog bpf_ops; struct frame_map fm; struct timeval start, end, diff; bool is_out_pcap = ctx->device_out && strstr(ctx->device_out, ".pcap"); const struct pcap_file_ops *pcap_out_ops = pcap_ops[PCAP_OPS_RW]; bug_on(!__pcap_io); if (!strncmp("-", ctx->device_in, strlen("-"))) { fd = dup_or_die(fileno(stdin)); close(fileno(stdin)); if (ctx->pcap == PCAP_OPS_MM) ctx->pcap = PCAP_OPS_SG; } else { /* O_NOATIME requires privileges, in case we don't have * them, retry without them at a minor cost of updating * atime in case the fs has been mounted as such. */ fd = open(ctx->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); if (fd < 0 && errno == EPERM) fd = open_or_die(ctx->device_in, O_RDONLY | O_LARGEFILE); if (fd < 0) panic("Cannot open file %s! %s.\n", ctx->device_in, strerror(errno)); } if (__pcap_io->init_once_pcap) __pcap_io->init_once_pcap(false); ret = __pcap_io->pull_fhdr_pcap(fd, &ctx->magic, &ctx->link_type); if (ret) panic("Error reading pcap header!\n"); if (__pcap_io->prepare_access_pcap) { ret = __pcap_io->prepare_access_pcap(fd, PCAP_MODE_RD, ctx->jumbo); if (ret) panic("Error prepare reading pcap!\n"); } fmemset(&fm, 0, sizeof(fm)); bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type); if (ctx->dump_bpf) bpf_dump_all(&bpf_ops); dissector_init_all(ctx->print_mode); out_len = round_up(1024 * 1024, RUNTIME_PAGE_SIZE); out = xmalloc_aligned(out_len, CO_CACHE_LINE_SIZE); if (ctx->device_out) { if (!strncmp("-", ctx->device_out, strlen("-"))) { fdo = dup_or_die(fileno(stdout)); close(fileno(stdout)); } else { fdo = open_or_die_m(ctx->device_out, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, DEFFILEMODE); } } if (is_out_pcap) { ret = pcap_out_ops->push_fhdr_pcap(fdo, ctx->magic, ctx->link_type); if (ret) panic("Error writing pcap header!\n"); } drop_privileges(ctx->enforce, ctx->uid, ctx->gid); printf("Running! Hang up with ^C!\n\n"); fflush(stdout); bug_on(gettimeofday(&start, NULL)); while (likely(sigint == 0)) { do { ret = __pcap_io->read_pcap(fd, &phdr, ctx->magic, out, out_len); if (unlikely(ret < 0)) goto out; if (unlikely(pcap_get_length(&phdr, ctx->magic) == 0)) { trunced++; continue; } if (unlikely(pcap_get_length(&phdr, ctx->magic) > out_len)) { pcap_set_length(&phdr, ctx->magic, out_len); trunced++; } } while (ctx->filter && !bpf_run_filter(&bpf_ops, out, pcap_get_length(&phdr, ctx->magic))); pcap_pkthdr_to_tpacket_hdr(&phdr, ctx->magic, &fm.tp_h, &fm.s_ll); ctx->tx_bytes += fm.tp_h.tp_len; ctx->tx_packets++; show_frame_hdr(out, fm.tp_h.tp_snaplen, ctx->link_type, &fm, ctx->print_mode, ctx->tx_packets); dissector_entry_point(out, fm.tp_h.tp_snaplen, ctx->link_type, ctx->print_mode, &fm.s_ll); if (is_out_pcap) { size_t pcap_len = pcap_get_length(&phdr, ctx->magic); int wlen = pcap_out_ops->write_pcap(fdo, &phdr, ctx->magic, out, pcap_len); if (unlikely(wlen != (int)pcap_get_total_length(&phdr, ctx->magic))) panic("Error writing to pcap!\n"); } else if (ctx->device_out) { translate_pcap_to_txf(fdo, out, fm.tp_h.tp_snaplen); } if (frame_count_max != 0) { if (ctx->tx_packets >= frame_count_max) { sigint = 1; break; } } } out: bug_on(gettimeofday(&end, NULL)); timersub(&end, &start, &diff); bpf_release(&bpf_ops); dissector_cleanup_all(); if (__pcap_io->prepare_close_pcap) __pcap_io->prepare_close_pcap(fd, PCAP_MODE_RD); xfree(out); fflush(stdout); printf("\n"); printf("\r%12lu packets outgoing\n", ctx->tx_packets); printf("\r%12lu packets truncated in file\n", trunced); printf("\r%12lu bytes outgoing\n", ctx->tx_bytes); printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); if (!strncmp("-", ctx->device_in, strlen("-"))) dup2(fd, fileno(stdin)); close(fd); if (ctx->device_out) { if (!strncmp("-", ctx->device_out, strlen("-"))) dup2(fdo, fileno(stdout)); close(fdo); } }
static void enter_mode_read_pcap(struct mode *mode) { int ret, fd, fdo = 0; struct pcap_pkthdr phdr; struct sock_fprog bpf_ops; struct tx_stats stats; struct frame_map fm; uint8_t *out; size_t out_len; unsigned long trunced = 0; struct timeval start, end, diff; if (!pcap_ops[mode->pcap]) panic("pcap group not supported!\n"); fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); ret = pcap_ops[mode->pcap]->pull_file_header(fd, &mode->link_type); if (ret) panic("error reading pcap header!\n"); if (pcap_ops[mode->pcap]->prepare_reading_pcap) { ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd); if (ret) panic("error prepare reading pcap!\n"); } fmemset(&fm, 0, sizeof(fm)); fmemset(&bpf_ops, 0, sizeof(bpf_ops)); fmemset(&stats, 0, sizeof(stats)); bpf_parse_rules(mode->filter, &bpf_ops); dissector_init_all(mode->print_mode); out_len = 64 * 1024; out = xmalloc_aligned(out_len, CO_CACHE_LINE_SIZE); printf("BPF:\n"); bpf_dump_all(&bpf_ops); printf("MD: RD %s ", pcap_ops[mode->pcap]->name); #ifdef _LARGEFILE64_SOURCE printf("lf64 "); #endif ioprio_print(); printf("\n"); if (mode->device_out) { fdo = open_or_die_m(mode->device_out, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR); } gettimeofday(&start, NULL); while (likely(sigint == 0)) { do { memset(&phdr, 0, sizeof(phdr)); ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr, out, out_len); if (unlikely(ret < 0)) goto out; if (unlikely(phdr.len == 0)) { trunced++; continue; } if (unlikely(phdr.len > out_len)) { phdr.len = out_len; trunced++; } } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len)); pcap_pkthdr_to_tpacket_hdr(&phdr, &fm.tp_h); stats.tx_bytes += fm.tp_h.tp_len; stats.tx_packets++; show_frame_hdr(&fm, mode->print_mode, RING_MODE_EGRESS); dissector_entry_point(out, fm.tp_h.tp_snaplen, mode->link_type, mode->print_mode); if (mode->device_out) { int i = 0; char bout[80]; slprintf(bout, sizeof(bout), "{\n "); write_or_die(fdo, bout, strlen(bout)); while (i < fm.tp_h.tp_snaplen) { slprintf(bout, sizeof(bout), "0x%02x, ", out[i]); write_or_die(fdo, bout, strlen(bout)); i++; if (i % 10 == 0) { slprintf(bout, sizeof(bout), "\n", out[i]); write_or_die(fdo, bout, strlen(bout)); if (i < fm.tp_h.tp_snaplen) { slprintf(bout, sizeof(bout), " ", out[i]); write_or_die(fdo, bout, strlen(bout)); } } } if (i % 10 != 0) { slprintf(bout, sizeof(bout), "\n"); write_or_die(fdo, bout, strlen(bout)); } slprintf(bout, sizeof(bout), "}\n\n"); write_or_die(fdo, bout, strlen(bout)); } if (frame_cnt_max != 0 && stats.tx_packets >= frame_cnt_max) { sigint = 1; break; } } out: gettimeofday(&end, NULL); diff = tv_subtract(end, start); fflush(stdout); printf("\n"); printf("\r%12lu frames outgoing\n", stats.tx_packets); printf("\r%12lu frames truncated (larger than mtu)\n", trunced); printf("\r%12lu bytes outgoing\n", stats.tx_bytes); printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); xfree(out); bpf_release(&bpf_ops); dissector_cleanup_all(); if (pcap_ops[mode->pcap]->prepare_close_pcap) pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ); close(fd); if (mode->device_out) close(fdo); }
static void enter_mode_pcap_to_tx(struct mode *mode) { int irq, ifindex, fd = 0, ret; unsigned int size, it = 0; struct ring tx_ring; struct frame_map *hdr; struct sock_fprog bpf_ops; struct tx_stats stats; uint8_t *out = NULL; unsigned long trunced = 0; struct timeval start, end, diff; if (!device_up_and_running(mode->device_out)) panic("Device not up and running!\n"); tx_sock = pf_socket(); if (!pcap_ops[mode->pcap]) panic("pcap group not supported!\n"); fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); ret = pcap_ops[mode->pcap]->pull_file_header(fd, &mode->link_type); if (ret) panic("error reading pcap header!\n"); if (pcap_ops[mode->pcap]->prepare_reading_pcap) { ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd); if (ret) panic("error prepare reading pcap!\n"); } fmemset(&tx_ring, 0, sizeof(tx_ring)); fmemset(&bpf_ops, 0, sizeof(bpf_ops)); fmemset(&stats, 0, sizeof(stats)); if (mode->rfraw) { mode->device_trans = xstrdup(mode->device_out); xfree(mode->device_out); enter_rfmon_mac80211(mode->device_trans, &mode->device_out); if (mode->link_type != LINKTYPE_IEEE802_11) panic("Wrong linktype of pcap!\n"); } ifindex = device_ifindex(mode->device_out); size = ring_size(mode->device_out, mode->reserve_size); bpf_parse_rules(mode->filter, &bpf_ops); set_packet_loss_discard(tx_sock); set_sockopt_hwtimestamp(tx_sock, mode->device_out); setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support); create_tx_ring(tx_sock, &tx_ring); mmap_tx_ring(tx_sock, &tx_ring); alloc_tx_ring_frames(&tx_ring); bind_tx_ring(tx_sock, &tx_ring, ifindex); dissector_init_all(mode->print_mode); if (mode->cpu >= 0 && ifindex > 0) { irq = device_irq_number(mode->device_out); device_bind_irq_to_cpu(mode->cpu, irq); printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq, mode->cpu); } if (mode->kpull) interval = mode->kpull; itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = interval; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = interval; setitimer(ITIMER_REAL, &itimer, NULL); printf("BPF:\n"); bpf_dump_all(&bpf_ops); printf("MD: TX %luus %s ", interval, pcap_ops[mode->pcap]->name); if (mode->rfraw) printf("802.11 raw via %s ", mode->device_out); #ifdef _LARGEFILE64_SOURCE printf("lf64 "); #endif ioprio_print(); printf("\n"); gettimeofday(&start, NULL); while (likely(sigint == 0)) { while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) { struct pcap_pkthdr phdr; hdr = tx_ring.frames[it].iov_base; /* Kernel assumes: data = ph.raw + po->tp_hdrlen - * sizeof(struct sockaddr_ll); */ out = ((uint8_t *) hdr) + TPACKET_HDRLEN - sizeof(struct sockaddr_ll); do { memset(&phdr, 0, sizeof(phdr)); ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr, out, ring_frame_size(&tx_ring)); if (unlikely(ret <= 0)) goto out; if (ring_frame_size(&tx_ring) < phdr.len) { phdr.len = ring_frame_size(&tx_ring); trunced++; } } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len)); pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h); stats.tx_bytes += hdr->tp_h.tp_len;; stats.tx_packets++; show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS); dissector_entry_point(out, hdr->tp_h.tp_snaplen, mode->link_type, mode->print_mode); kernel_may_pull_from_tx(&hdr->tp_h); next_slot_prewr(&it, &tx_ring); if (unlikely(sigint == 1)) break; if (frame_cnt_max != 0 && stats.tx_packets >= frame_cnt_max) { sigint = 1; break; } } } out: gettimeofday(&end, NULL); diff = tv_subtract(end, start); fflush(stdout); printf("\n"); printf("\r%12lu frames outgoing\n", stats.tx_packets); printf("\r%12lu frames truncated (larger than frame)\n", trunced); printf("\r%12lu bytes outgoing\n", stats.tx_bytes); printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); bpf_release(&bpf_ops); dissector_cleanup_all(); destroy_tx_ring(tx_sock, &tx_ring); if (mode->rfraw) leave_rfmon_mac80211(mode->device_trans, mode->device_out); close(tx_sock); if (pcap_ops[mode->pcap]->prepare_close_pcap) pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ); close(fd); }
static void enter_mode_pcap_to_tx(struct mode *mode) { int irq, ifindex, fd = 0, ret; unsigned int size, it = 0; struct ring tx_ring; struct frame_map *hdr; struct sock_fprog bpf_ops; struct tx_stats stats; uint8_t *out = NULL; unsigned long trunced = 0; struct timeval start, end, diff; int filen = 0; struct pcap_timeval *pcap_time; /* if (!device_up_and_running(mode->device_out)) panic("Device not up and running!\n"); */ if (!pcap_ops[mode->pcap]) panic("pcap group not supported!\n"); //Moved here /* ifindex = device_ifindex(mode->device_out); //Make n devices out of it. From here size = ring_size(mode->device_out, mode->reserve_size); bpf_parse_rules(mode->filter, &bpf_ops); set_packet_loss_discard(tx_sock); set_sockopt_hwtimestamp(tx_sock, mode->device_out); setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support); create_tx_ring(tx_sock, &tx_ring); mmap_tx_ring(tx_sock, &tx_ring); alloc_tx_ring_frames(&tx_ring); bind_tx_ring(tx_sock, &tx_ring, ifindex); dissector_init_all(mode->print_mode); if (mode->cpu >= 0 && ifindex > 0) { irq = device_irq_number(mode->device_out); device_bind_irq_to_cpu(mode->cpu, irq); printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq, mode->cpu); } //Till here. Make n TXRings. One for each NIC. */ //Moved to here end int x = 0; for (filen = 0; filen < num_of_pcaps; filen++) { tx_sock = pf_socket(); mode->device_in = pcaplist[filen]; printf("\n \n File selected is: %s \n", mode->device_in); fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME); //Need to do for each file ret = pcap_ops[mode->pcap]->pull_file_header(fd, &mode->link_type); if (ret) { panic("error reading pcap header!\n"); continue; } if (pcap_ops[mode->pcap]->prepare_reading_pcap) { ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd); if (ret) { panic("error prepare reading pcap!\n"); continue; } } fmemset(&tx_ring, 0, sizeof(tx_ring)); fmemset(&bpf_ops, 0, sizeof(bpf_ops)); fmemset(&stats, 0, sizeof(stats)); if (mode->rfraw) { mode->device_trans = xstrdup(mode->device_out); xfree(mode->device_out); enter_rfmon_mac80211(mode->device_trans, &mode->device_out); if (mode->link_type != LINKTYPE_IEEE802_11) panic("Wrong linktype of pcap!\n"); continue; } ifindex = device_ifindex(mode->device_out); //Make n devices out of it. From here size = ring_size(mode->device_out, mode->reserve_size); bpf_parse_rules(mode->filter, &bpf_ops); set_packet_loss_discard(tx_sock); set_sockopt_hwtimestamp(tx_sock, mode->device_out); setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support); create_tx_ring(tx_sock, &tx_ring); mmap_tx_ring(tx_sock, &tx_ring); alloc_tx_ring_frames(&tx_ring); bind_tx_ring(tx_sock, &tx_ring, ifindex); //Till here. Make n TXRings. One for each NIC. dissector_init_all(mode->print_mode); if (mode->cpu >= 0 && ifindex > 0) { irq = device_irq_number(mode->device_out); device_bind_irq_to_cpu(mode->cpu, irq); printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq, mode->cpu); } if (mode->kpull) interval = mode->kpull; itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = interval; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = interval; //for fixed delay need to SET this setitimer(ITIMER_REAL, &itimer, NULL); printf("BPF:\n"); bpf_dump_all(&bpf_ops); printf("MD: TX %luus %s ", interval, pcap_ops[mode->pcap]->name); if (mode->rfraw) printf("802.11 raw via %s ", mode->device_out); #ifdef _LARGEFILE64_SOURCE printf("lf64 "); #endif ioprio_print(); printf("\n"); gettimeofday(&start, NULL); sigint = 0; while (likely(sigint == 0)) { while (user_may_pull_from_tx (tx_ring.frames[it].iov_base)) { struct pcap_pkthdr phdr; hdr = tx_ring.frames[it].iov_base; /* Kernel assumes: data = ph.raw + po->tp_hdrlen - * sizeof(struct sockaddr_ll); */ out = ((uint8_t *) hdr) + TPACKET_HDRLEN - sizeof(struct sockaddr_ll); do { memset(&phdr, 0, sizeof(phdr)); ret = pcap_ops[mode->pcap]-> read_pcap_pkt(fd, &phdr, out, ring_frame_size (&tx_ring)); if (unlikely(ret <= 0)) goto out; if (ring_frame_size(&tx_ring) < phdr.len) { phdr.len = ring_frame_size(&tx_ring); trunced++; } } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len)); pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h); if (stats.tx_packets == 0) { pcap_time = &phdr.ts; beginning_tv_sec = pcap_time->tv_sec; beginning_tv_usec = pcap_time->tv_usec; } /* * START OF BLOCK The below routines are only if Speed or PPS is set else they won't execute * */ if (gbit_s > 0) { /* computing max rate */ pps = ((gbit_s * 1000000000) / 8 /*byte */ ) / (8 /*Preamble */ + avg_send_len + 4 /*CRC*/ + 12 /*IFG*/); td = (double)(hz / pps); tick_delta = (ticks) td; //printf("Number of %d-byte Packet Per Second at %.2f Gbit/s: %.2f\n", (avg_send_len + 4 /*CRC*/), gbit_s, pps); } else if (pps > 0) { td = (double)(hz / pps); tick_delta = (ticks) td; } //END OF BLOCK /* show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS); dissector_entry_point(out, hdr->tp_h.tp_snaplen, mode->link_type, mode->print_mode); */ //x++; kernel_may_pull_from_tx(&hdr->tp_h); next_slot_prewr(&it, &tx_ring); stats.tx_bytes += hdr->tp_h.tp_len;; stats.tx_packets++; send_len += hdr->tp_h.tp_len; avg_send_len = send_len / stats.tx_packets; if (unlikely(sigint == 1)) break; if (frame_cnt_max != 0 && stats.tx_packets >= frame_cnt_max) { //sigint = 1; break; } //START OF BLOCK if (gbit_s != 0 || pps > 0) tick_start = getticks(); if (gbit_s > 0 || pps > 0) { /* rate set */ while ((getticks() - tick_start) < (num_pkt_good_sent * tick_delta)) ; } else if (gbit_s < 0) { /* real pcap rate --FULL SYNC MODE */ pcap_time = &phdr.ts; ticks ticks_from_beginning = (((pcap_time->tv_sec - beginning_tv_sec) * 1000000) + (pcap_time->tv_usec - beginning_tv_usec)) * hz / 1000000; //delta time of this pkt from beginning of pcap /* h-> is this packet header and beginning is 1st packet's header */ if (ticks_from_beginning == 0) tick_start = getticks(); /* first packet, resetting time */ while ((getticks() - tick_start) < ticks_from_beginning) ; } //pps routine end //END OF BLOCK } } out: gettimeofday(&end, NULL); diff = tv_subtract(end, start); fflush(stdout); printf("\n"); printf("\r%12lu frames outgoing\n", stats.tx_packets); printf("\r%12lu frames truncated (larger than frame)\n", trunced); printf("\r%12lu bytes outgoing\n", stats.tx_bytes); printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); bpf_release(&bpf_ops); dissector_cleanup_all(); destroy_tx_ring(tx_sock, &tx_ring); if (mode->rfraw) leave_rfmon_mac80211(mode->device_trans, mode->device_out); close(tx_sock); if (pcap_ops[mode->pcap]->prepare_close_pcap) pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ); close(fd); } }