int pfring_bundle_read(pfring_bundle *bundle, u_char** buffer, u_int buffer_len, struct pfring_pkthdr *hdr, u_int8_t wait_for_incoming_packet) { u_int i, sock_id = 0, num_found, rc; struct timeval ts = { 0 }; redo_pfring_bundle_read: switch(bundle->policy) { case pick_round_robin: for(i=0; i<bundle->num_sockets; i++) { bundle->last_read_socket = (bundle->last_read_socket + 1) % bundle->num_sockets; if(pfring_there_is_pkt_available(bundle->sockets[bundle->last_read_socket])) { return(pfring_recv(bundle->sockets[bundle->last_read_socket], buffer, buffer_len, hdr, wait_for_incoming_packet)); } } break; case pick_fifo: num_found = 0; for(i=0; i<bundle->num_sockets; i++) { pfring *ring = bundle->sockets[i]; if(pfring_there_is_pkt_available(ring)) { struct pfring_pkthdr *header = (struct pfring_pkthdr*)&ring->slots[ring->slots_info->remove_off]; if((num_found == 0) || is_before(&header->ts, &ts)) { memcpy(&ts, &header->ts, sizeof(struct timeval)); num_found++, sock_id = i; } } } if(num_found > 0) { return(pfring_recv(bundle->sockets[sock_id], buffer, buffer_len, hdr, wait_for_incoming_packet)); } break; } if(wait_for_incoming_packet) { rc = pfring_bundle_poll(bundle, bundle->sockets[0]->poll_duration); if(rc > 0) { goto redo_pfring_bundle_read; } else return(rc); } return(0); }
int pfring_recv_parsed(pfring *ring, u_char** buffer, u_int buffer_len, struct pfring_pkthdr *hdr, u_int8_t wait_for_incoming_packet, u_int8_t level /* 1..4 */, u_int8_t add_timestamp, u_int8_t add_hash) { int rc = pfring_recv(ring, buffer, buffer_len, hdr, wait_for_incoming_packet); if(rc > 0) rc = pfring_parse_pkt(*buffer, hdr, level, add_timestamp, add_hash); return rc; }
void* PfRingDevice::captureThreadMain(void *ptr) { PfRingDevice* device = (PfRingDevice*)ptr; int coreId = device->getCurrentCoreId().Id; pfring* ring = NULL; LOG_DEBUG("Starting capture thread %d", coreId); ring = device->m_CoreConfiguration[coreId].Channel; if (ring == NULL) { LOG_ERROR("Couldn't find ring for core %d. Exiting capture thread", coreId); return (void*)NULL; } while (!device->m_StopThread) { // if buffer is NULL PF_RING avoids copy of the data uint8_t* buffer = NULL; uint32_t bufferLen = 0; // in multi-threaded mode flag PF_RING_REENTRANT is set, and this flag doesn't work with zero copy // so I need to allocate a buffer and set buffer to point to it if (device->m_ReentrantMode) { uint8_t tempBuffer[MAX_PACKET_SIZE]; buffer = tempBuffer; bufferLen = MAX_PACKET_SIZE; } struct pfring_pkthdr pktHdr; int recvRes = pfring_recv(ring, &buffer, bufferLen, &pktHdr, 0); if (recvRes > 0) { // if caplen < len it means we don't have the whole packet. Treat this case as packet drop // TODO: add this packet to dropped packet stats // if (pktHdr.caplen != pktHdr.len) // { // LOG_ERROR("Packet dropped due to len != caplen"); // continue; // } RawPacket rawPacket(buffer, pktHdr.caplen, pktHdr.ts, false); device->m_OnPacketsArriveCallback(&rawPacket, 1, coreId, device, device->m_OnPacketsArriveUserCookie); } else if (recvRes < 0) { LOG_ERROR("pfring_recv returned an error: [Err=%d]", recvRes); } } LOG_DEBUG("Exiting capture thread %d", coreId); return (void*)NULL; }
void* packet_consumer_thread(void* _id) { long thread_id = (long)_id; #ifdef HAVE_PTHREAD_SETAFFINITY_NP if(numCPU > 1) { /* Bind this thread to a specific core */ cpu_set_t cpuset; u_long core_id; int s; if (thread_core_affinity[thread_id] != -1) core_id = thread_core_affinity[thread_id] % numCPU; else core_id = (thread_id + 1) % numCPU; CPU_ZERO(&cpuset); CPU_SET(core_id, &cpuset); if((s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)) != 0) fprintf(stderr, "Error while binding thread %ld to core %ld: errno=%i\n", thread_id, core_id, s); else { printf("Set thread %lu on core %lu/%u\n", thread_id, core_id, numCPU); } } #endif while(!do_shutdown) { u_char *buffer = NULL; struct pfring_pkthdr hdr; if(pfring_recv(ring[thread_id], &buffer, 0, &hdr, wait_for_packet) > 0) { dummyProcesssPacket(&hdr, buffer, (u_char*)thread_id); } else { if(wait_for_packet == 0) sched_yield(); //usleep(1); } } return(NULL); }
int pfring_loop(pfring *ring, pfringProcesssPacket looper, const u_char *user_bytes) { u_char *buffer = NULL; struct pfring_pkthdr hdr; int rc = 0; if(!ring) return -1; ring->break_recv_loop = 0; while(!ring->break_recv_loop) { rc = pfring_recv(ring, &buffer, 0, &hdr, 1); if(rc < 0) break; else if(rc > 0) looper(&hdr, buffer, user_bytes); } return(rc); }
void cluster::_Run() { std::string thread_name = device_name + "_cluster"; prctl(PR_SET_NAME, thread_name.c_str()); int len = 2048; u_char *buffer = new u_char[len]; struct pfring_pkthdr *hdr = (pfring_pkthdr *)buffer; u_char* lpPkt = buffer + sizeof(struct pfring_pkthdr); int waitable = 1; /* 0-->non-blocking, otherwise blocking*/ //u_int8_t level = 4; /* 2 of OSI-7*/ //u_int8_t addtimestamp = 1; /* 1 --> add timetamp */ //u_int8_t addhash = 0; /* 0 --> don't add hash */ pfring_enable_ring(ring); //解码的结果集 _nic_stat_session_tuple tuple; for(;;) { int ret = pfring_recv(ring, (u_char**)&lpPkt, PF_CAP_LEN, hdr, waitable); if( ret > 0 ) { decode((uint8_t *)lpPkt, hdr->caplen); tuple.init(); fill_tuple(tuple, hdr->caplen); cluster_stat_flow(&tuple); } } }
/** * \brief Recieves packets from an interface via libpfring. * * This function recieves packets from an interface and passes * the packet on to the pfring callback function. * * \param tv pointer to ThreadVars * \param data pointer that gets cast into PfringThreadVars for ptv * \param slot slot containing task information * \retval TM_ECODE_OK on success * \retval TM_ECODE_FAILED on failure */ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) { SCEnter(); uint16_t packet_q_len = 0; PfringThreadVars *ptv = (PfringThreadVars *)data; Packet *p = NULL; struct pfring_pkthdr hdr; TmSlot *s = (TmSlot *)slot; time_t last_dump = 0; struct timeval current_time; ptv->slot = s->slot_next; while(1) { if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { SCReturnInt(TM_ECODE_OK); } /* make sure we have at least one packet in the packet pool, to prevent * us from alloc'ing packets at line rate */ do { packet_q_len = PacketPoolSize(); if (unlikely(packet_q_len == 0)) { PacketPoolWait(); } } while (packet_q_len == 0); p = PacketGetFromQueueOrAlloc(); if (p == NULL) { SCReturnInt(TM_ECODE_FAILED); } PKT_SET_SRC(p, PKT_SRC_WIRE); /* Some flavours of PF_RING may fail to set timestamp - see PF-RING-enabled libpcap code*/ hdr.ts.tv_sec = hdr.ts.tv_usec = 0; /* Depending on what compile time options are used for pfring we either return 0 or -1 on error and always 1 for success */ #ifdef HAVE_PFRING_RECV_UCHAR u_char *pkt_buffer = GET_PKT_DIRECT_DATA(p); u_int buffer_size = GET_PKT_DIRECT_MAX_SIZE(p); int r = pfring_recv(ptv->pd, &pkt_buffer, buffer_size, &hdr, LIBPFRING_WAIT_FOR_INCOMING); /* Check for Zero-copy if buffer size is zero */ if (buffer_size == 0) { PacketSetData(p, pkt_buffer, hdr.caplen); } #else int r = pfring_recv(ptv->pd, (char *)GET_PKT_DIRECT_DATA(p), (u_int)GET_PKT_DIRECT_MAX_SIZE(p), &hdr, LIBPFRING_WAIT_FOR_INCOMING); #endif /* HAVE_PFRING_RECV_UCHAR */ if (r == 1) { //printf("RecievePfring src %" PRIu32 " sport %" PRIu32 " dst %" PRIu32 " dstport %" PRIu32 "\n", // hdr.parsed_pkt.ipv4_src,hdr.parsed_pkt.l4_src_port, hdr.parsed_pkt.ipv4_dst,hdr.parsed_pkt.l4_dst_port); PfringProcessPacket(ptv, &hdr, p); if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { TmqhOutputPacketpool(ptv->tv, p); SCReturnInt(TM_ECODE_FAILED); } /* Trigger one dump of stats every second */ TimeGet(¤t_time); if (current_time.tv_sec != last_dump) { PfringDumpCounters(ptv); last_dump = current_time.tv_sec; } } else { SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r); TmqhOutputPacketpool(ptv->tv, p); SCReturnInt(TM_ECODE_FAILED); } SCPerfSyncCountersIfSignalled(tv); } return TM_ECODE_OK; }
int pfring_bundle_read(pfring_bundle *bundle, u_char** buffer, u_int buffer_len, struct pfring_pkthdr *hdr, u_int8_t wait_for_incoming_packet) { int i, sock_id = -1, found, rc, empty_rings, scans; struct timespec ts = { 0 }; struct timespec tmpts; u_int8_t founds[32] = { 0 }; redo_pfring_bundle_read: switch(bundle->policy) { case pick_round_robin: for(i=0; i<bundle->num_sockets; i++) { rc = pfring_recv(bundle->sockets[bundle->last_read_socket], buffer, buffer_len, hdr, 0); if(++bundle->last_read_socket == bundle->num_sockets) bundle->last_read_socket = 0; if(rc > 0) return(rc); } break; case pick_fifo: found = 0; empty_rings = 0; scans = 0; sockets_scan: scans++; for(i=0; i<bundle->num_sockets; i++) { if(founds[i] == 0) { pfring *ring = bundle->sockets[i]; rc = pfring_next_pkt_time(ring, &tmpts); if(rc == 0) { if(!found || timespec_is_before(&tmpts, &ts)) { memcpy(&ts, &tmpts, sizeof(struct timespec)); found = 1, founds[i] = 1; sock_id = i; } } else if (rc == PF_RING_ERROR_NO_PKT_AVAILABLE) { empty_rings = 1; } else { /* error */ } } } if(found) { #ifdef EXTRA_SAFE if(empty_rings && (scans == 1)) goto sockets_scan; /* scanning ring twice (safety check) */ #endif return(pfring_recv(bundle->sockets[sock_id], buffer, buffer_len, hdr, 0)); } break; } if(wait_for_incoming_packet) { rc = pfring_bundle_poll(bundle, bundle->sockets[0]->poll_duration); if(rc > 0) goto redo_pfring_bundle_read; else return(rc); } return(0); }
static int read_packet(struct stream_pfring* st, int block){ assert(st); do { /* read next frame */ struct pfring_pkthdr hdr; switch ( pfring_recv(st->pd, (u_char**)&st->frame[st->base.writePos], 0, &hdr, block) ){ case 0: return 0; case 1: break; case -1: fprintf(stderr, "pfring_recv(..) failed.\n"); return 0; } char* dst = st->frame[st->base.writePos]; /* Setup pointers */ const struct ethhdr* eh = (const struct ethhdr*)dst; const struct sendhead* sh = (const struct sendhead*)(dst + sizeof(struct ethhdr)); /* Check if it is a valid packet and if it was destinationed here */ int match; if ( (match=match_ma_pkt(st, eh)) == -1 ){ continue; } #ifdef DEBUG fprintf(stderr, "got measurement frame with %d capture packets [BU: %3.2f%%]\n", ntohl(sh->nopkts), 0.0f); #endif /* increase packet count */ st->base.stat.recv += ntohl(sh->nopkts); /* if no sequencenr is set some additional checks are made. * they will also run when the sequence number wraps, but that ok since the * sequence number will match in that case anyway. */ if ( st->seqnum[match] == 0 ){ /* read stream version */ struct file_header_t FH; FH.version.major=ntohs(sh->version.major); FH.version.minor=ntohs(sh->version.minor); /* ensure we can read this version */ if ( !is_valid_version(&FH) ){ perror("invalid stream version"); break; } /* this is set last, as we want to wait until a packet with valid version * arrives before proceeding. */ st->seqnum[match] = ntohl(sh->sequencenr); } match_inc_seqnr(&st->base, &st->seqnum[match], sh); st->base.writePos = (st->base.writePos+1) % st->num_frames; /* This indicates a flush from the sender.. */ if( ntohs(sh->flush) == 1 ){ fprintf(stderr, "Sender terminated.\n"); st->base.flushed=1; } return 1; } while (1); return 0; }
/** * \brief Recieves packets from an interface via libpfring. * * This function recieves packets from an interface and passes * the packet on to the pfring callback function. * * \param tv pointer to ThreadVars * \param data pointer that gets cast into PfringThreadVars for ptv * \param slot slot containing task information * \retval TM_ECODE_OK on success * \retval TM_ECODE_FAILED on failure */ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) { SCEnter(); PfringThreadVars *ptv = (PfringThreadVars *)data; Packet *p = NULL; struct pfring_pkthdr hdr; TmSlot *s = (TmSlot *)slot; time_t last_dump = 0; u_int buffer_size; u_char *pkt_buffer; ptv->slot = s->slot_next; /* we have to enable the ring here as we need to do it after all * the threads have called pfring_set_cluster(). */ int rc = pfring_enable_ring(ptv->pd); if (rc != 0) { SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable_ring failed returned %d ", rc); SCReturnInt(TM_ECODE_FAILED); } while(1) { if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { SCReturnInt(TM_ECODE_OK); } /* make sure we have at least one packet in the packet pool, to prevent * us from alloc'ing packets at line rate */ PacketPoolWait(); p = PacketGetFromQueueOrAlloc(); if (p == NULL) { SCReturnInt(TM_ECODE_FAILED); } PKT_SET_SRC(p, PKT_SRC_WIRE); /* Some flavours of PF_RING may fail to set timestamp - see PF-RING-enabled libpcap code*/ hdr.ts.tv_sec = hdr.ts.tv_usec = 0; /* Check for Zero-copy mode */ if (ptv->flags & PFRING_FLAGS_ZERO_COPY) { buffer_size = 0; pkt_buffer = NULL; } else { buffer_size = GET_PKT_DIRECT_MAX_SIZE(p); pkt_buffer = GET_PKT_DIRECT_DATA(p); } int r = pfring_recv(ptv->pd, &pkt_buffer, buffer_size, &hdr, LIBPFRING_WAIT_FOR_INCOMING); if (likely(r == 1)) { /* profiling started before blocking pfring_recv call, so * reset it here */ PACKET_PROFILING_RESTART(p); /* Check for Zero-copy mode */ if (ptv->flags & PFRING_FLAGS_ZERO_COPY) { PacketSetData(p, pkt_buffer, hdr.caplen); } //printf("RecievePfring src %" PRIu32 " sport %" PRIu32 " dst %" PRIu32 " dstport %" PRIu32 "\n", // hdr.parsed_pkt.ipv4_src,hdr.parsed_pkt.l4_src_port, hdr.parsed_pkt.ipv4_dst,hdr.parsed_pkt.l4_dst_port); PfringProcessPacket(ptv, &hdr, p); if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { TmqhOutputPacketpool(ptv->tv, p); SCReturnInt(TM_ECODE_FAILED); } /* Trigger one dump of stats every second */ if (p->ts.tv_sec != last_dump) { PfringDumpCounters(ptv); last_dump = p->ts.tv_sec; } } else if (unlikely(r == 0)) { if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { SCReturnInt(TM_ECODE_OK); } /* pfring didn't use the packet yet */ TmThreadsCaptureInjectPacket(tv, ptv->slot, p); } else { SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r); TmqhOutputPacketpool(ptv->tv, p); SCReturnInt(TM_ECODE_FAILED); } StatsSyncCountersIfSignalled(tv); } return TM_ECODE_OK; }
static int pfring_daq_acquire(void *handle, int cnt, DAQ_Analysis_Func_t callback, #if (DAQ_API_VERSION >= 0x00010002) DAQ_Meta_Func_t metaback, #endif void *user) { Pfring_Context_t *context =(Pfring_Context_t *) handle; int ret = 0, i, current_ring_idx = context->num_devices - 1, rx_ring_idx; struct pollfd pfd[DAQ_PF_RING_MAX_NUM_DEVICES]; hash_filtering_rule hash_rule; memset(&hash_rule, 0, sizeof(hash_rule)); context->analysis_func = callback; context->breakloop = 0; for (i = 0; i < context->num_devices; i++) pfring_enable_ring(context->ring_handles[i]); while((!context->breakloop) && ((cnt == -1) || (cnt > 0))) { struct pfring_pkthdr phdr; DAQ_PktHdr_t hdr; DAQ_Verdict verdict; memset(&phdr, 0, sizeof(phdr)); if(pfring_daq_reload_requested) pfring_daq_reload(context); for (i = 0; i < context->num_devices; i++) { current_ring_idx = (current_ring_idx + 1) % context->num_devices; ret = pfring_recv(context->ring_handles[current_ring_idx], &context->pkt_buffer, 0, &phdr, 0 /* Dont't wait */); if (ret > 0) break; } if(ret <= 0) { /* No packet to read: let's poll */ int rc; for (i = 0; i < context->num_devices; i++) { pfd[i].fd = pfring_get_selectable_fd(context->ring_handles[i]); pfd[i].events = POLLIN; pfd[i].revents = 0; } rc = poll(pfd, context->num_devices, context->timeout); if(rc < 0) { if(errno == EINTR) break; DPE(context->errbuf, "%s: Poll failed: %s(%d)", __FUNCTION__, strerror(errno), errno); return DAQ_ERROR; } } else { hdr.caplen = phdr.caplen; hdr.pktlen = phdr.len; hdr.ts = phdr.ts; #if (DAQ_API_VERSION >= 0x00010002) hdr.ingress_index = phdr.extended_hdr.if_index; hdr.egress_index = -1; hdr.ingress_group = -1; hdr.egress_group = -1; #else hdr.device_index = phdr.extended_hdr.if_index; #endif hdr.flags = 0; rx_ring_idx = current_ring_idx; context->stats.packets_received++; verdict = context->analysis_func(user, &hdr,(u_char*)context->pkt_buffer); if(verdict >= MAX_DAQ_VERDICT) verdict = DAQ_VERDICT_PASS; if (phdr.extended_hdr.parsed_pkt.eth_type == 0x0806 /* ARP */ ) verdict = DAQ_VERDICT_PASS; switch(verdict) { case DAQ_VERDICT_BLACKLIST: /* Block the packet and block all future packets in the same flow systemwide. */ if (context->use_kernel_filters) { pfring_parse_pkt(context->pkt_buffer, &phdr, 4, 0, 0); /* or use pfring_recv_parsed() to force parsing. */ hash_rule.rule_id = context->filter_count++; hash_rule.vlan_id = phdr.extended_hdr.parsed_pkt.vlan_id; hash_rule.proto = phdr.extended_hdr.parsed_pkt.l3_proto; memcpy(&hash_rule.host_peer_a, &phdr.extended_hdr.parsed_pkt.ipv4_src, sizeof(ip_addr)); memcpy(&hash_rule.host_peer_b, &phdr.extended_hdr.parsed_pkt.ipv4_dst, sizeof(ip_addr)); hash_rule.port_peer_a = phdr.extended_hdr.parsed_pkt.l4_src_port; hash_rule.port_peer_b = phdr.extended_hdr.parsed_pkt.l4_dst_port; hash_rule.plugin_action.plugin_id = NO_PLUGIN_ID; if (context->mode == DAQ_MODE_PASSIVE && context->num_reflector_devices > rx_ring_idx) { /* lowlevelbridge ON */ hash_rule.rule_action = reflect_packet_and_stop_rule_evaluation; snprintf(hash_rule.reflector_device_name, REFLECTOR_NAME_LEN, "%s", context->reflector_devices[rx_ring_idx]); } else { hash_rule.rule_action = dont_forward_packet_and_stop_rule_evaluation; } pfring_handle_hash_filtering_rule(context->ring_handles[rx_ring_idx], &hash_rule, 1 /* add_rule */); /* Purge rules idle (i.e. with no packet matching) for more than 1h */ pfring_purge_idle_hash_rules(context->ring_handles[rx_ring_idx], context->idle_rules_timeout); #if DEBUG printf("[DEBUG] %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d Verdict=%d Action=%d\n", hash_rule.host_peer_a.v4 >> 24 & 0xFF, hash_rule.host_peer_a.v4 >> 16 & 0xFF, hash_rule.host_peer_a.v4 >> 8 & 0xFF, hash_rule.host_peer_a.v4 >> 0 & 0xFF, hash_rule.port_peer_a & 0xFFFF, hash_rule.host_peer_b.v4 >> 24 & 0xFF, hash_rule.host_peer_b.v4 >> 16 & 0xFF, hash_rule.host_peer_b.v4 >> 8 & 0xFF, hash_rule.host_peer_b.v4 >> 0 & 0xFF, hash_rule.port_peer_b & 0xFFFF, verdict, hash_rule.rule_action); #endif } break; case DAQ_VERDICT_WHITELIST: /* Pass the packet and fastpath all future packets in the same flow systemwide. */ case DAQ_VERDICT_IGNORE: /* Pass the packet and fastpath all future packets in the same flow for this application. */ /* Setting a rule for reflectiong packets when lowlevelbridge is ON could be an optimization here, * but we can't set "forward" (reflector won't work) or "reflect" (packets reflected twice) hash rules */ case DAQ_VERDICT_PASS: /* Pass the packet */ case DAQ_VERDICT_REPLACE: /* Pass a packet that has been modified in-place.(No resizing allowed!) */ if (context->mode == DAQ_MODE_INLINE) { pfring_daq_send_packet(context, context->ring_handles[rx_ring_idx ^ 0x1], hdr.caplen, context->ring_handles[rx_ring_idx], context->ifindexes[rx_ring_idx ^ 0x1]); } break; case DAQ_VERDICT_BLOCK: /* Block the packet. */ /* Nothing to do really */ break; case MAX_DAQ_VERDICT: /* No way we can reach this point */ break; } context->stats.verdicts[verdict]++; if(cnt > 0) cnt--; } }
int main(int argc, char* argv[]) { pfring *a_ring, *b_ring; char *a_dev = NULL, *b_dev = NULL, c; u_int8_t verbose = 0, use_pfring_send = 0; int a_ifindex, b_ifindex; int bind_core = -1; u_int16_t watermark = 1; while((c = getopt(argc,argv, "ha:b:c:fvpg:w:")) != -1) { switch(c) { case 'h': printHelp(); return 0; break; case 'a': a_dev = strdup(optarg); break; case 'b': b_dev = strdup(optarg); break; case 'p': use_pfring_send = 1; break; case 'v': verbose = 1; break; case 'g': bind_core = atoi(optarg); break; case 'w': watermark = atoi(optarg); break; } } if ((!a_dev) || (!b_dev)) { printf("You must specify two devices!\n"); return -1; } if(strcmp(a_dev, b_dev) == 0) { printf("Bridge devices must be different!\n"); return -1; } /* Device A */ if((a_ring = pfring_open(a_dev, MAX_PKT_LEN, PF_RING_PROMISC | PF_RING_LONG_HEADER | (use_pfring_send ? 0 : PF_RING_RX_PACKET_BOUNCE)) ) == NULL) { printf("pfring_open error for %s [%s]\n", a_dev, strerror(errno)); return(-1); } pfring_set_application_name(a_ring, "pfbridge-a"); pfring_set_direction(a_ring, rx_only_direction); pfring_set_socket_mode(a_ring, recv_only_mode); pfring_set_poll_watermark(a_ring, watermark); pfring_get_bound_device_ifindex(a_ring, &a_ifindex); /* Device B */ if((b_ring = pfring_open(b_dev, MAX_PKT_LEN, PF_RING_PROMISC|PF_RING_LONG_HEADER)) == NULL) { printf("pfring_open error for %s [%s]\n", b_dev, strerror(errno)); pfring_close(a_ring); return(-1); } pfring_set_application_name(b_ring, "pfbridge-b"); pfring_set_socket_mode(b_ring, send_only_mode); pfring_get_bound_device_ifindex(b_ring, &b_ifindex); /* Enable Sockets */ if (pfring_enable_ring(a_ring) != 0) { printf("Unable enabling ring 'a' :-(\n"); pfring_close(a_ring); pfring_close(b_ring); return(-1); } if(use_pfring_send) { if (pfring_enable_ring(b_ring)) { printf("Unable enabling ring 'b' :-(\n"); pfring_close(a_ring); pfring_close(b_ring); return(-1); } } else { pfring_close(b_ring); } signal(SIGALRM, my_sigalarm); alarm(1); if(bind_core >= 0) bind2core(bind_core); while(1) { u_char *buffer; struct pfring_pkthdr hdr; if(pfring_recv(a_ring, &buffer, 0, &hdr, 1) > 0) { int rc; if(use_pfring_send) { rc = pfring_send(b_ring, (char *) buffer, hdr.caplen, 1); if(rc < 0) printf("pfring_send(caplen=%u <= mtu=%u?) error %d\n", hdr.caplen, b_ring->mtu_len, rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } else { rc = pfring_send_last_rx_packet(a_ring, b_ifindex); if(rc < 0) printf("pfring_send_last_rx_packet() error %d\n", rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } if(rc >= 0) num_sent++; } } pfring_close(a_ring); if(use_pfring_send) pfring_close(b_ring); return(0); }
int main(int argc, char* argv[]) { pfring *a_ring, *b_ring; char *a_dev = NULL, *b_dev = NULL, c; u_int8_t verbose = 0, use_pfring_send = 0; int a_ifindex, b_ifindex; while((c = getopt(argc,argv, "ha:b:c:fvp")) != -1) { switch(c) { case 'h': printHelp(); return 0; break; case 'a': a_dev = strdup(optarg); break; case 'b': b_dev = strdup(optarg); break; case 'p': use_pfring_send = 1; break; case 'v': verbose = 1; break; } } if ((!a_dev) || (!b_dev)) { printf("You must specify two devices!\n"); return -1; } if(strcmp(a_dev, b_dev) == 0) { printf("Bridge devices must be different!\n"); return -1; } /* open devices */ if((a_ring = pfring_open(a_dev, 1500, PF_RING_PROMISC|PF_RING_LONG_HEADER)) == NULL) { printf("pfring_open error for %s [%s]\n", a_dev, strerror(errno)); return(-1); } else { pfring_set_application_name(a_ring, "pfbridge-a"); pfring_set_direction(a_ring, rx_and_tx_direction); pfring_get_bound_device_ifindex(a_ring, &a_ifindex); } if((b_ring = pfring_open(b_dev, 1500, PF_RING_PROMISC|PF_RING_LONG_HEADER)) == NULL) { printf("pfring_open error for %s [%s]\n", b_dev, strerror(errno)); pfring_close(a_ring); return(-1); } else { pfring_set_application_name(b_ring, "pfbridge-b"); pfring_set_direction(b_ring, rx_and_tx_direction); pfring_get_bound_device_ifindex(b_ring, &b_ifindex); } /* Enable rings */ pfring_enable_ring(a_ring); if(use_pfring_send) pfring_enable_ring(b_ring); else pfring_close(b_ring); signal(SIGALRM, my_sigalarm); alarm(1); while(1) { u_char *buffer; struct pfring_pkthdr hdr; if(pfring_recv(a_ring, &buffer, 0, &hdr, 1) > 0) { int rc; if(use_pfring_send) { rc = pfring_send(b_ring, (char*)buffer, hdr.caplen, 1); if(rc < 0) printf("pfring_send_last_rx_packet() error %d\n", rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } else { rc = pfring_send_last_rx_packet(a_ring, b_ifindex); if(rc < 0) printf("pfring_send_last_rx_packet() error %d\n", rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } if(rc >= 0) num_sent++; } } pfring_close(a_ring); if(use_pfring_send) pfring_close(b_ring); return(0); }
int main(int argc, char *argv[]) { char *dev; // The device to sniff on char errbuf[PCAP_ERRBUF_SIZE]; // Error string if any operation fails struct bpf_program fp; // The compiled filter (not used) char filter_exp[] = "port 23"; // The filter expression (not used) bpf_u_int32 mask; // Our subnet mask bpf_u_int32 net; // Our network ID struct pfring_pkthdr header; // The header that pfring gives us u_char *packet; // The actual packet int flags,num_pkts=0; // Flags to pass for opening pfring instance, number of packets captured memset(&header,0,sizeof(header)); signal(SIGINT,sigproc); dev = argv[1]; // Set the device manually to arg[1] printf("\nCapture device: %s\n", dev); makefilename(); flags = PF_RING_PROMISC; if((handle = pfring_open(dev, 1520, flags)) == NULL) { //MAX_CAPLEN instead of 1520 printf("pfring_open error"); return(-1); } else { pfring_set_application_name(handle, "packetcapture"); } pfring_enable_ring(handle); dumper = pcap_dump_open(pcap_open_dead(DLT_EN10MB, 16384), filename); //16384 is MTU if(dumper == NULL) { printf("Unable to create dump file %s\n", filename); return(-1); } while(1) { if(pfring_recv(handle, &packet, 0, &header, 1 ) > 0) { //wait for packet, blocking call if(num_pkts>=PACKETS_PER_FILE) { num_pkts = 0; pcap_dump_close(dumper); filenumber++; makefilename(); dumper = pcap_dump_open(pcap_open_dead(DLT_EN10MB, 16384), filename); if(dumper == NULL) { printf("Unable to create dump file %s\n", filename); exit(1); } } pcap_dump((u_char*)dumper, (struct pcap_pkthdr*)&header, packet); fprintf(stdout, "."); fflush(stdout); num_pkts++; } } pcap_dump_close(dumper); pfring_close(handle); return 0; }