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);
}
示例#2
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);
}
示例#5
0
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);
}
示例#6
0
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);
		}
	}
	
}
示例#7
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();

    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(&current_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;
}
示例#8
0
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);
}
示例#9
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;
}
示例#10
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;
}
示例#11
0
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--;
    }
  }
示例#12
0
文件: pfbridge.c 项目: bigfg/PF_RING
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);
}
示例#13
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);
}
示例#14
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;
}