int main(int argc OVS_UNUSED, char *argv[]) { struct ofp_match expected_match; FILE *flows, *pcap; int retval; int n = 0, errors = 0; set_program_name(argv[0]); flows = stdin; pcap = fdopen(3, "rb"); if (!pcap) { ovs_fatal(errno, "failed to open fd 3 for reading"); } retval = pcap_read_header(pcap); if (retval) { ovs_fatal(retval > 0 ? retval : 0, "reading pcap header failed"); } while (fread(&expected_match, sizeof expected_match, 1, flows)) { struct ofpbuf *packet; struct ofp_match extracted_match; struct cls_rule rule; struct flow flow; n++; retval = pcap_read(pcap, &packet); if (retval == EOF) { ovs_fatal(0, "unexpected end of file reading pcap file"); } else if (retval) { ovs_fatal(retval, "error reading pcap file"); } flow_extract(packet, 0, 1, &flow); cls_rule_init_exact(&flow, 0, &rule); ofputil_cls_rule_to_match(&rule, &extracted_match); if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) { char *exp_s = ofp_match_to_string(&expected_match, 2); char *got_s = ofp_match_to_string(&extracted_match, 2); errors++; printf("mismatch on packet #%d (1-based).\n", n); printf("Packet:\n"); ofp_print_packet(stdout, packet->data, packet->size, packet->size); ovs_hex_dump(stdout, packet->data, packet->size, 0, true); printf("Expected flow:\n%s\n", exp_s); printf("Actually extracted flow:\n%s\n", got_s); printf("\n"); free(exp_s); free(got_s); } ofpbuf_delete(packet); } printf("checked %d packets, %d errors\n", n, errors); return errors != 0; }
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { register int n; for (;;) { if (p->sf.rfile != NULL) n = pcap_offline_read(p, cnt, callback, user); else { /* * XXX keep reading until we get something * (or an error occurs) */ do { n = pcap_read(p, cnt, callback, user); } while (n == 0); } if (n <= 0) return (n); if (cnt > 0) { cnt -= n; if (cnt <= 0) return (0); } } }
int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { if (p->sf.rfile != NULL) return (pcap_offline_read(p, cnt, callback, user)); return (pcap_read(p, cnt, callback, user)); }
int main(int argc, const char** argv) { if (2 > argc) { print_help(); return 0; } pcap cap; if (QP_ERROR == pcap_open(argv[1], &cap)) { return QP_ERROR; } cap.pkt_process = pcap_process; pcap_read(&cap); pcap_close(&cap); return 0; }
static void * tx_thread_transmit(void * arg) { struct pollfd pfd; struct frame_map * header = NULL; int ret = 0; uint32_t pkt_put = 0; uint32_t i = 0; struct netsniff_ng_tx_thread_context * thread_ctx = (struct netsniff_ng_tx_thread_context *) arg; struct netsniff_ng_tx_nic_context * nic_ctx = NULL; struct packet_ctx * pkt_ctx = NULL; struct ring_buff * rb = NULL; if (thread_ctx == NULL) { pthread_exit(NULL); } pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); nic_ctx = &thread_ctx->nic_ctx; pkt_ctx = &nic_ctx->generic.pkt_ctx; rb = &nic_ctx->nic_rb; memset(pkt_ctx, 0, sizeof(*pkt_ctx)); memset(&pfd, 0, sizeof(pfd)); pfd.fd = nic_ctx->generic.dev_fd; pfd.events = POLLOUT; info("--- Transmitting ---\n\n"); do { for (i = 0; i < rb->layout.tp_block_nr; i++) { header = (struct frame_map *)rb->frames[i].iov_base; pkt_ctx->pkt_buf = (uint8_t *) header + TPACKET_HDRLEN - sizeof(struct sockaddr_ll); switch (header->tp_h.tp_status) { case TP_STATUS_AVAILABLE: while ((pkt_ctx->pkt_len = pcap_read(nic_ctx->generic.pcap_fd, pkt_ctx)) != 0) { /* If the fetch packet does not match the BPF, take the next one */ if (bpf_filter(&nic_ctx->generic.bpf, pkt_ctx->pkt_buf, pkt_ctx->pkt_len)) { break; } } /* No packets to replay or error, time to exit */ if (pkt_ctx->pkt_len == 0) goto flush_pkt; gettimeofday(&pkt_ctx->pkt_ts, NULL); /* Mark packet as ready to send */ header->tp_h.tp_status = TP_STATUS_SEND_REQUEST; header->tp_h.tp_len = header->tp_h.tp_snaplen = pkt_ctx->pkt_len; header->tp_h.tp_sec = pkt_ctx->pkt_ts.tv_sec; header->tp_h.tp_usec = pkt_ctx->pkt_ts.tv_usec; pkt_put++; break; case TP_STATUS_WRONG_FORMAT: warn("An error during transfer!\n"); exit(EXIT_FAILURE); break; default: break; } } flush_pkt: ret = send(nic_ctx->generic.dev_fd, NULL, 0, MSG_DONTWAIT); info("send() returned %i: %s\n", ret, strerror(errno)); if (ret < 0) { err("Cannot flush tx_ring with send"); } /* Now we wait that the kernel place all packet on the medium */ ret = poll(&pfd, 1, -1); if (ret < 0) err("An error occured while polling on %s\n", nic_ctx->generic.dev_name); } while (pkt_ctx->pkt_len); info("Placed %u packets\n", pkt_put); pthread_exit(NULL); }