Ejemplo n.º 1
0
void bpf_parse_rules(char *rulefile, struct sock_fprog *bpf, uint32_t link_type)
{
	int ret;
	char buff[256];
	struct sock_filter sf_single = { 0x06, 0, 0, 0xFFFFFFFF };
	FILE *fp;

	if (rulefile == NULL) {
		bpf->len = 1;
		bpf->filter = xmalloc(sizeof(sf_single));

		fmemcpy(&bpf->filter[0], &sf_single, sizeof(sf_single));
		return;
	}

	fp = fopen(rulefile, "r");
	if (!fp) {
		bpf_try_compile(rulefile, bpf, link_type);
		return;
	}

	fmemset(buff, 0, sizeof(buff));
	while (fgets(buff, sizeof(buff), fp) != NULL) {
		buff[sizeof(buff) - 1] = 0;

		if (buff[0] != '{') {
			fmemset(buff, 0, sizeof(buff));
			continue;
		}

		fmemset(&sf_single, 0, sizeof(sf_single));
		ret = sscanf(buff, "{ 0x%x, %u, %u, 0x%08x },",
			     (unsigned int *) &sf_single.code,
			     (unsigned int *) &sf_single.jt,
			     (unsigned int *) &sf_single.jf,
			     (unsigned int *) &sf_single.k);
		if (unlikely(ret != 4))
			panic("BPF syntax error!\n");

		bpf->len++;
		bpf->filter = xrealloc(bpf->filter, 1,
				       bpf->len * sizeof(sf_single));

		fmemcpy(&bpf->filter[bpf->len - 1], &sf_single,
			sizeof(sf_single));
		fmemset(buff, 0, sizeof(buff));
	}

	fclose(fp);

	if (unlikely(__bpf_validate(bpf) == 0))
		panic("This is not a valid BPF program!\n");
}
Ejemplo n.º 2
0
void far *DynAlloc(char *what, unsigned num, unsigned size)
{
  void far *now;
  unsigned total = num * size;
  struct DynS far *Dynp = MK_FP(FP_SEG(LoL), FP_OFF(&Dyn));

#ifndef DEBUG
  UNREFERENCED_PARAMETER(what);
#endif

  if ((ULONG) total + Dynp->Allocated > 0xffff)
  {
    printf("PANIC:Dyn %lu\n", (ULONG) total + Dynp->Allocated);
    for (;;) ;
  }

  DebugPrintf(("DYNDATA:allocating %s - %u * %u bytes, total %u, %u..%u\n",
               what, num, size, total, Dynp->Allocated,
               Dynp->Allocated + total));

  now = (void far *)&Dynp->Buffer[Dynp->Allocated];
  fmemset(now, 0, total);

  Dynp->Allocated += total;

  return now;
}
Ejemplo n.º 3
0
// GetVersionEx
// memset
int WINAPI IC_GetOSVersion(BOOL bMajor)
{
	t_fGetVersionEx fGetVersionEx = NULL;
	t_fmemset fmemset = NULL;

	DWORD *pFuncPtr = NULL;

	_asm	MOV	pFuncPtr, EAX
	
	pFuncPtr -= 2;
	fmemset = (t_fmemset)*pFuncPtr;

	pFuncPtr--;
	fGetVersionEx = (t_fGetVersionEx)*pFuncPtr;

	OSVERSIONINFO osver;

	fmemset(&osver, 0, sizeof(osver));

	osver.dwOSVersionInfoSize = sizeof(osver);

	fGetVersionEx(&osver);

	return osver.dwMajorVersion; 
}
Ejemplo n.º 4
0
static void apply_csum16(int csum_id)
{
	int j, i = csum_id;
	size_t csum_max = packet_dyn[i].slen;

	for (j = 0; j < csum_max; ++j) {
		uint16_t sum = 0;
		struct csum16 *csum = &packet_dyn[i].csum[j];

		fmemset(&packets[i].payload[csum->off], 0, sizeof(sum));

		switch (csum->which) {
		case CSUM_IP:
			if (csum->to >= packets[i].len)
				csum->to = packets[i].len - 1;
			sum = calc_csum(packets[i].payload + csum->from,
					csum->to - csum->from + 1, 0);
			break;
		case CSUM_UDP:
			sum = p4_csum((void *) packets[i].payload + csum->from,
				      packets[i].payload + csum->to,
				      (packets[i].len - csum->to),
				      IPPROTO_UDP);
			break;
		case CSUM_TCP:
			sum = p4_csum((void *) packets[i].payload + csum->from,
				      packets[i].payload + csum->to,
				      (packets[i].len - csum->to),
				      IPPROTO_TCP);
			break;
		}

		fmemcpy(&packets[i].payload[csum->off], &sum, sizeof(sum));
	}
}
Ejemplo n.º 5
0
static struct cpu_stats *setup_shared_var(unsigned long cpus)
{
	int fd;
	char zbuff[cpus * sizeof(struct cpu_stats)], file[256];
	struct cpu_stats *buff;

	fmemset(zbuff, 0, sizeof(zbuff));
	slprintf(file, sizeof(file), ".tmp_mmap.%u", (unsigned int) rand());

	fd = creat(file, S_IRUSR | S_IWUSR);
	bug_on(fd < 0);
	close(fd);

	fd = open_or_die_m(file, O_RDWR | O_CREAT | O_TRUNC,
			   S_IRUSR | S_IWUSR);
	write_or_die(fd, zbuff, sizeof(zbuff));

	buff = (void *) mmap(0, sizeof(zbuff), PROT_READ | PROT_WRITE,
			     MAP_SHARED, fd, 0);
	if (buff == (void *) -1)
		panic("Cannot setup shared variable!\n");

	close(fd);
	unlink(file);

	memset(buff, 0, sizeof(zbuff));

	return buff;
}
Ejemplo n.º 6
0
/*
 * /dev/zero code
 */
size_t zero_read(struct inode *inode, struct file *filp, char *data, int len)
{
    debugmem("zero_read()\n");
    fmemset(data, current->mm.dseg, 0, (size_t) len);
    filp->f_pos += len;
    return (size_t)len;
}
Ejemplo n.º 7
0
int curve25519_proto_init(struct curve25519_proto *proto, unsigned char *pubkey_remote,
			  size_t len, char *home, int server)
{
	int fd;
	ssize_t ret;
	char path[PATH_MAX];
	unsigned char secretkey_own[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES];
	unsigned char publickey_own[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES];

	fmemset(secretkey_own, 0, sizeof(secretkey_own));
	fmemset(publickey_own, 0, sizeof(publickey_own));

	if (!pubkey_remote || len != sizeof(publickey_own))
		return -EINVAL;

	slprintf(path, sizeof(path), "%s/%s", home, FILE_PRIVKEY);
	fd = open_or_die(path, O_RDONLY);

	ret = read(fd, secretkey_own, sizeof(secretkey_own));
	if (ret != sizeof(secretkey_own)) {
		xmemset(secretkey_own, 0, sizeof(secretkey_own));
		panic("Cannot read private key!\n");
	}

	close(fd);

	crypto_scalarmult_curve25519_base(publickey_own, secretkey_own);

	if (!crypto_verify_32(publickey_own, pubkey_remote)) {
		xmemset(secretkey_own, 0, sizeof(secretkey_own));
		xmemset(publickey_own, 0, sizeof(publickey_own));
		panic("PANIC: remote end has same public key as you have!!!\n");
	}

	crypto_box_beforenm(proto->key, pubkey_remote, secretkey_own);

	xmemset(proto->enonce, 0, sizeof(proto->enonce));
	xmemset(proto->dnonce, 0, sizeof(proto->dnonce));

	xmemset(secretkey_own, 0, sizeof(secretkey_own));
	xmemset(publickey_own, 0, sizeof(publickey_own));

	return 0;
}
Ejemplo n.º 8
0
static void finish_multi_pcap_file(struct mode *mode, int fd)
{
	pcap_ops[mode->pcap]->fsync_pcap(fd);
	if (pcap_ops[mode->pcap]->prepare_close_pcap)
		pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
	close(fd);

	fmemset(&itimer, 0, sizeof(itimer));
	setitimer(ITIMER_REAL, &itimer, NULL);
}
Ejemplo n.º 9
0
BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode)
{
  sft FAR *s;
  LONG lPosit;
  COUNT nRead;
  psp FAR *p = MK_FP(cu_psp, 0);

  /* Convert to fcb if necessary                                  */
  lpFcb = ExtFcbToFcb(lpXfcb);

  /* Get the SFT block that contains the SFT      */
  if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
    return FALSE;

  /* If this is not opened another error          */
  if (s->sft_count == 0)
    return FALSE;

  /* Now update the fcb and compute where we need to position     */
  /* to.                                                          */
  lPosit = FcbRec() * lpFcb->fcb_recsiz;
  if (SftSeek(s, lPosit, 0) != SUCCESS)
  {
    *nErrorCode = FCB_ERR_EOF;
    return FALSE;
  }

  /* Do the read                                                  */
  nRead = DosReadSft(s, lpFcb->fcb_recsiz, p->ps_dta, nErrorCode);

  /* Now find out how we will return and do it.                   */
  if (nRead == lpFcb->fcb_recsiz)
  {
    *nErrorCode = FCB_SUCCESS;
    FcbNextRecord(lpFcb);
    return TRUE;
  }
  else if (nRead < 0)
  {
    *nErrorCode = FCB_ERR_EOF;
    return TRUE;
  }
  else if (nRead == 0)
  {
    *nErrorCode = FCB_ERR_NODATA;
    return FALSE;
  }
  else
  {
    fmemset(&p->ps_dta[nRead], 0, lpFcb->fcb_recsiz - nRead);
    *nErrorCode = FCB_ERR_EOF;
    FcbNextRecord(lpFcb);
    return FALSE;
  }
}
Ejemplo n.º 10
0
void destroy_rx_ring(int sock, struct ring *ring)
{
	fmemset(&ring->layout, 0, sizeof(ring->layout));
	setsockopt(sock, SOL_PACKET, PACKET_RX_RING, &ring->layout,
		   sizeof(ring->layout));

	munmap(ring->mm_space, ring->mm_len);
	ring->mm_len = 0;

	xfree(ring->frames);
}
Ejemplo n.º 11
0
static void finish_multi_pcap_file(struct ctx *ctx, int fd)
{
	__pcap_io->fsync_pcap(fd);

	if (__pcap_io->prepare_close_pcap)
		__pcap_io->prepare_close_pcap(fd, PCAP_MODE_WR);

	close(fd);

	fmemset(&itimer, 0, sizeof(itimer));
	setitimer(ITIMER_REAL, &itimer, NULL);
}
Ejemplo n.º 12
0
void alloc_ring_frames_generic(struct ring *ring, int num, size_t size)
{
	int i;
	size_t len = num * sizeof(*ring->frames);

	ring->frames = xmalloc_aligned(len, CO_CACHE_LINE_SIZE);
	fmemset(ring->frames, 0, len);

	for (i = 0; i < num; ++i) {
		ring->frames[i].iov_len = size;
		ring->frames[i].iov_base = ring->mm_space + (i * size);
	}
}
Ejemplo n.º 13
0
void destroy_tx_ring(int sock, struct ring *ring)
{
	int ret;

	munmap(ring->mm_space, ring->mm_len);
	ring->mm_len = 0;

	fmemset(&ring->layout, 0, sizeof(ring->layout));
	ret = setsockopt(sock, SOL_PACKET, PACKET_TX_RING, &ring->layout,
			 sizeof(ring->layout));
	if (unlikely(ret))
		panic("Cannot destroy the TX_RING: %s!\n", strerror(errno));

	xfree(ring->frames);
}
Ejemplo n.º 14
0
static int pcap_mmap_push_file_header(int fd, uint32_t linktype)
{
	ssize_t ret;
	struct pcap_filehdr hdr;

	fmemset(&hdr, 0, sizeof(hdr));
	pcap_prepare_header(&hdr, linktype, 0, PCAP_DEFAULT_SNAPSHOT_LEN);

	ret = write_or_die(fd, &hdr, sizeof(hdr));
	if (unlikely(ret != sizeof(hdr))) {
		whine("Failed to write pkt file header!\n");
		return -EIO;
	}

	return 0;
}
Ejemplo n.º 15
0
static void print_pcap_file_stats(int sock, struct ctx *ctx)
{
	int ret;
	struct tpacket_stats kstats;
	socklen_t slen = sizeof(kstats);

	fmemset(&kstats, 0, sizeof(kstats));

	ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
	if (unlikely(ret))
		panic("Cannot get packet statistics!\n");
	
	if (ctx->print_mode == PRINT_NONE) {
		printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
		       kstats.tp_drops);
		fflush(stdout);
	}
}
Ejemplo n.º 16
0
void setup_rx_ring_layout(int sock, struct ring *ring, unsigned int size,
			  int jumbo_support)
{
	fmemset(&ring->layout, 0, sizeof(ring->layout));

	ring->layout.tp_block_size = (jumbo_support ?
				      getpagesize() << 4 :
				      getpagesize() << 2);
	ring->layout.tp_frame_size = (jumbo_support ?
				      TPACKET_ALIGNMENT << 12 :
				      TPACKET_ALIGNMENT << 7);
	ring->layout.tp_block_nr = size / ring->layout.tp_block_size;
	ring->layout.tp_frame_nr = ring->layout.tp_block_size /
				   ring->layout.tp_frame_size *
				   ring->layout.tp_block_nr;

	bug_on(ring->layout.tp_block_size < ring->layout.tp_frame_size);
	bug_on((ring->layout.tp_block_size % ring->layout.tp_frame_size) != 0);
	bug_on((ring->layout.tp_block_size % getpagesize()) != 0);
}
Ejemplo n.º 17
0
void bind_ring_generic(int sock, struct ring *ring, int ifindex)
{
	int ret;
	/* The {TX,RX}_RING registers itself to the networking stack with
	 * dev_add_pack(), so we have one single RX_RING for all devs
	 * otherwise you'll get the packet twice.
	 */
	fmemset(&ring->s_ll, 0, sizeof(ring->s_ll));

	ring->s_ll.sll_family = AF_PACKET;
	ring->s_ll.sll_protocol = htons(ETH_P_ALL);
	ring->s_ll.sll_ifindex = ifindex;
	ring->s_ll.sll_hatype = 0;
	ring->s_ll.sll_halen = 0;
	ring->s_ll.sll_pkttype = 0;

	ret = bind(sock, (struct sockaddr *) &ring->s_ll, sizeof(ring->s_ll));
	if (ret < 0)
		panic("Cannot bind {TX,RX}_RING!\n");
}
Ejemplo n.º 18
0
static void print_pcap_file_stats(int sock, struct ctx *ctx, unsigned long skipped)
{
	int ret;
	unsigned long good, bad;
	struct tpacket_stats kstats;
	socklen_t slen = sizeof(kstats);

	fmemset(&kstats, 0, sizeof(kstats));

	ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
	if (unlikely(ret))
		panic("Cannot get packet statistics!\n");
	
	if (ctx->print_mode == PRINT_NONE) {
		good = kstats.tp_packets - kstats.tp_drops - skipped;
		bad = kstats.tp_drops + skipped;

		printf(".(+%lu/-%lu)", good, bad);
		fflush(stdout);
	}
}
Ejemplo n.º 19
0
void setup_tx_ring_layout(int sock, struct ring *ring, unsigned int size,
			  bool jumbo_support)
{
	fmemset(&ring->layout, 0, sizeof(ring->layout));

	ring->layout.tp_block_size = (jumbo_support ?
				      getpagesize() << 4 :
				      getpagesize() << 2);

	ring->layout.tp_frame_size = (jumbo_support ?
				      TPACKET_ALIGNMENT << 12 :
				      TPACKET_ALIGNMENT << 7);

	ring->layout.tp_block_nr = size / ring->layout.tp_block_size;
	ring->layout.tp_frame_nr = ring->layout.tp_block_size /
				   ring->layout.tp_frame_size *
				   ring->layout.tp_block_nr;

	set_sockopt_tpacket_v2(sock);

	ring_verify_layout(ring);
}
Ejemplo n.º 20
0
/* The following code is 8086 dependant                         */
VOID new_psp(psp FAR * p, int psize)
{
  REG COUNT i;
  psp FAR *q = MK_FP(cu_psp, 0);

  /* Clear out new psp first                              */
  fmemset(p, 0, sizeof(psp));

  /* initialize all entries and exits                     */
  /* CP/M-like exit point                                 */
  p->ps_exit = 0x20cd;

  /* CP/M-like entry point - jump to special entry        */
  p->ps_farcall = 0xea;
  p->ps_reentry = (VOID(FAR *) ())cpm_entry;
  /* unix style call - 0xcd 0x21 0xcb (int 21, retf)      */
  p->ps_unix[0] = 0xcd;
  p->ps_unix[1] = 0x21;
  p->ps_unix[2] = 0xcb;

  /* Now for parent-child relationships                   */
  /* parent psp segment                                   */
  p->ps_parent = cu_psp;
  /* previous psp pointer                                 */
  p->ps_prevpsp = q;

  /* Environment and memory useage parameters             */
  /* memory size in paragraphs                            */
  p->ps_size = psize;
  /* environment paragraph                                */
  p->ps_environ = 0;
  /* process dta                                          */
  p->ps_dta = (BYTE FAR *) (&p->ps_cmd_count);

  /* terminate address                                    */
  p->ps_isv22 = (VOID(INRPT FAR *) (void))getvec(0x22);
  /* break address                                        */
  p->ps_isv23 = (VOID(INRPT FAR *) (void))getvec(0x23);
  /* critical error address                               */
  p->ps_isv24 = (VOID(INRPT FAR *) (void))getvec(0x24);

  /* File System parameters                               */
  /* user stack pointer - int 21                          */
  p->ps_stack = q->ps_stack;
  /* file table - 0xff is unused                          */
  for (i = 0; i < 20; i++)
    p->ps_files[i] = 0xff;

  /* maximum open files                                   */
  p->ps_maxfiles = 20;
  /* open file table pointer                              */
  p->ps_filetab = p->ps_files;

  /* clone the file table                                 */
  if (p!=q)
  {
    REG COUNT i;

    for (i = 0; i < 20; i++)
    {
      if (q->ps_filetab[i] != 0xff && CloneHandle(i) >= 0)
        p->ps_filetab[i] = q->ps_filetab[i];
      else
        p->ps_filetab[i] = 0xff;
    }
  }

  /* first command line argument                          */
  p->ps_fcb1.fcb_drive = 0;
  /* second command line argument                         */
  p->ps_fcb2.fcb_drive = 0;

  /* local command line                                   */
  p->ps_cmd_count = 0;          /* command tail                 */
  p->ps_cmd[0] = 0;             /* command tail                 */
  if (RootPsp == (seg) ~ 0)
    RootPsp = FP_SEG(p);
}
Ejemplo n.º 21
0
Archivo: rd.c Proyecto: KP1533TM2/elks
static int rd_ioctl(register struct inode *inode, struct file *file,
		    unsigned int cmd, unsigned int arg)
{
    unsigned long size;
    unsigned int i;
    int j, k, target = DEVICE_NR(inode->i_rdev);

    if (!suser())
	return -EPERM;
    debug2("RD: ioctl %d %s\n", target, (cmd ? "kill" : "make"));
    switch (cmd) {
    case RDCREATE:
	if (rd_info[target].flags && RD_BUSY) {
	    return -EBUSY;
	} else {
	    /* allocate memory */

#if 0
	    rd_info[target].size = 0;
#endif

	    k = -1;
	    for (i = 0; i <= (arg - 1) / ((SEG_SIZE / 1024) * P_SIZE); i++) {
		j = find_free_seg();	/* find free place in queue */
		debug1("RD: ioctl find_free_seg() = %d\n", j);
		if (j == -1) {
		    rd_dealloc(target);
		    return -ENOMEM;
		}
		if (i == 0)
		    rd_info[target].index = j;

		if (i == (arg / ((SEG_SIZE / 1024) * P_SIZE)))
		    /* size in 16 byte pagez = (arg % 64) * 64 */
		    size =
			(arg % ((SEG_SIZE / 1024) * P_SIZE)) *
			((SEG_SIZE / 1024) * P_SIZE);
		else
		    size = SEG_SIZE;

		rd_segment[j].segment = mm_alloc(size);
		if (rd_segment[j].segment == -1) {
		    rd_dealloc(target);
		    return -ENOMEM;
		}
		debug4("RD: ioctl pass: %d, allocated %d pages, rd_segment[%d].segment = 0x%x\n",
		       i, (int) size, j, rd_segment[j].segment);

		/* recalculate int size to reflect size in sectors, not pages */
		size = size / DIVISOR;

		rd_segment[j].seg_size = size;	/* size in sectors */
		debug2("RD: ioctl rd_segment[%d].seg_size = %d sectors\n",
		       j, rd_segment[j].seg_size);
		rd_info[target].size += rd_segment[j].seg_size;	/* size in 512 B blocks */
		size = (long) rd_segment[j].seg_size * SECTOR_SIZE;
		debug1("RD: ioctl size = %ld\n", size);

		/* this terrible hack makes sure fmemset clears whole segment even if size == 64 KB :) */
		if (size != ((long) SEG_SIZE * (long) P_SIZE)) {
		    debug2("RD: ioctl calling fmemset(0, 0x%x, 0, %d) ..\n",
			   rd_segment[j].segment, (int) size);
		    fmemset(0, rd_segment[j].segment, 0, (int) size);	/* clear seg_size * SECTOR_SIZE bytes */
		} else {
		    debug2("RD: ioctl calling fmemset(0, 0x%x, 0, %d) ..\n",
			   rd_segment[j].segment, (int) (size / 2));
		    fmemset(0, rd_segment[j].segment, 0, (int) (size / 2));	/* we could hardcode 32768 instead of size / 2 here */
		    debug3("rd_ioctl(): calling fmemset(%d, 0x%x, 0, %d) ..\n",
			   (int) (size / 2), rd_segment[j].segment,
			   (int) (size / 2));
		    fmemset((size / 2), rd_segment[j].segment, 0,
			    (int) (size / 2));
		}

		if (k != -1)
		    rd_segment[k].next = j;	/* set link to next index */
		k = j;
	    }
	    rd_info[target].flags = RD_BUSY;
	    debug3("RD: ioctl ramdisk %d created, size = %d blocks, index = %d\n",
		 target, rd_info[target].size, rd_info[target].index);
	}
	debug("RD: ioctl about to return 0\n");
	return 0;
    case RDDESTROY:
	if (rd_info[target].flags && RD_BUSY) {
	    invalidate_inodes(inode->i_rdev);
	    invalidate_buffers(inode->i_rdev);
	    rd_dealloc(target);
	    rd_info[target].flags = 0;
	    return 0;
	} else
	    return -EINVAL;
    }
    return -EINVAL;
}
Ejemplo n.º 22
0
static void recv_only_or_dump(struct ctx *ctx)
{
	short ifflags = 0;
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct sock_fprog bpf_ops;
	struct timeval start, end, diff;
	struct block_desc *pbd;
	unsigned long frame_count = 0;

	sock = pf_socket();

	if (ctx->rfraw) {
		ctx->device_trans = xstrdup(ctx->device_in);
		xfree(ctx->device_in);

		enter_rfmon_mac80211(ctx->device_trans, &ctx->device_in);
		ctx->link_type = LINKTYPE_IEEE802_11;
	}

	fmemset(&rx_ring, 0, sizeof(rx_ring));
	fmemset(&rx_poll, 0, sizeof(rx_poll));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(ctx->device_in);

	size = ring_size(ctx->device_in, ctx->reserve_size);

	enable_kernel_bpf_jit_compiler();

	bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type);
	if (ctx->dump_bpf)
		bpf_dump_all(&bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	ret = set_sockopt_hwtimestamp(sock, ctx->device_in);
	if (ret == 0 && ctx->verbose)
		printf("HW timestamping enabled\n");

	setup_rx_ring_layout(sock, &rx_ring, size, true, true);
	create_rx_ring(sock, &rx_ring, ctx->verbose);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(sock, &rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(ctx->print_mode);

	if (ctx->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(ctx->device_in);
		device_set_irq_affinity(irq, ctx->cpu);

		if (ctx->verbose)
			printf("IRQ: %s:%d > CPU%d\n",
			       ctx->device_in, irq, ctx->cpu);
	}

	if (ctx->promiscuous)
		ifflags = enter_promiscuous_mode(ctx->device_in);

	if (dump_to_pcap(ctx) && __pcap_io->init_once_pcap)
		__pcap_io->init_once_pcap();

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (dump_to_pcap(ctx)) {
		__label__ try_file;
		struct stat stats;

		fmemset(&stats, 0, sizeof(stats));
		ret = stat(ctx->device_out, &stats);
		if (ret < 0) {
			ctx->dump_dir = 0;
			goto try_file;
		}

		ctx->dump_dir = S_ISDIR(stats.st_mode);
		if (ctx->dump_dir) {
			fd = begin_multi_pcap_file(ctx);
		} else {
		try_file:
			fd = begin_single_pcap_file(ctx);
		}
	}

	printf("Running! Hang up with ^C!\n\n");
	fflush(stdout);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx_block((pbd = (void *)
				rx_ring.frames[it].iov_base))) {
			walk_t3_block(pbd, ctx, sock, &fd, &frame_count);

			kernel_may_pull_from_rx_block(pbd);
			it = (it + 1) % rx_ring.layout3.tp_block_nr;

			if (unlikely(sigint == 1))
				break;
		}

		poll(&rx_poll, 1, -1);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (!(ctx->dump_dir && ctx->print_mode == PRINT_NONE)) {
		sock_rx_net_stats(sock, frame_count);

		printf("\r%12lu  sec, %lu usec in total\n",
		       diff.tv_sec, diff.tv_usec);
	} else {
		printf("\n\n");
		fflush(stdout);
	}

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);

	if (ctx->promiscuous)
		leave_promiscuous_mode(ctx->device_in, ifflags);

	if (ctx->rfraw)
		leave_rfmon_mac80211(ctx->device_trans, ctx->device_in);

	if (dump_to_pcap(ctx)) {
		if (ctx->dump_dir)
			finish_multi_pcap_file(ctx, fd);
		else
			finish_single_pcap_file(ctx, fd);
	}

	close(sock);
}
Ejemplo n.º 23
0
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);
	}
}
Ejemplo n.º 24
0
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);
}
Ejemplo n.º 25
0
static void receive_to_xmit(struct ctx *ctx)
{
	short ifflags = 0;
	uint8_t *in, *out;
	int rx_sock, ifindex_in, ifindex_out;
	unsigned int size_in, size_out, it_in = 0, it_out = 0;
	unsigned long frame_count = 0;
	struct frame_map *hdr_in, *hdr_out;
	struct ring tx_ring, rx_ring;
	struct pollfd rx_poll;
	struct sock_fprog bpf_ops;

	if (!strncmp(ctx->device_in, ctx->device_out, IFNAMSIZ))
		panic("Ingress/egress devices must be different!\n");
	if (!device_up_and_running(ctx->device_out))
		panic("Egress device not up and running!\n");

	rx_sock = pf_socket();
	tx_sock = pf_socket();

	fmemset(&tx_ring, 0, sizeof(tx_ring));
	fmemset(&rx_ring, 0, sizeof(rx_ring));
	fmemset(&rx_poll, 0, sizeof(rx_poll));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex_in = device_ifindex(ctx->device_in);
	ifindex_out = device_ifindex(ctx->device_out);

	size_in = ring_size(ctx->device_in, ctx->reserve_size);
	size_out = ring_size(ctx->device_out, ctx->reserve_size);

	enable_kernel_bpf_jit_compiler();

	bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type);
	if (ctx->dump_bpf)
		bpf_dump_all(&bpf_ops);
	bpf_attach_to_sock(rx_sock, &bpf_ops);

	setup_rx_ring_layout(rx_sock, &rx_ring, size_in, ctx->jumbo, false);
	create_rx_ring(rx_sock, &rx_ring, ctx->verbose);
	mmap_rx_ring(rx_sock, &rx_ring);
	alloc_rx_ring_frames(rx_sock, &rx_ring);
	bind_rx_ring(rx_sock, &rx_ring, ifindex_in);
	prepare_polling(rx_sock, &rx_poll);

	set_packet_loss_discard(tx_sock);
	setup_tx_ring_layout(tx_sock, &tx_ring, size_out, 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_out);

	dissector_init_all(ctx->print_mode);

	 if (ctx->promiscuous)
		ifflags = enter_promiscuous_mode(ctx->device_in);

	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);

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it_in].iov_base)) {
			__label__ next;

			hdr_in = rx_ring.frames[it_in].iov_base;
			in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;

			frame_count++;

			if (ctx->packet_type != -1)
				if (ctx->packet_type != hdr_in->s_ll.sll_pkttype)
					goto next;

			hdr_out = tx_ring.frames[it_out].iov_base;
			out = ((uint8_t *) hdr_out) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);

			for (; !user_may_pull_from_tx(tx_ring.frames[it_out].iov_base) &&
			       likely(!sigint);) {
				if (ctx->randomize)
					next_rnd_slot(&it_out, &tx_ring);
				else {
					it_out++;
					if (it_out >= tx_ring.layout.tp_frame_nr)
						it_out = 0;
				}

				hdr_out = tx_ring.frames[it_out].iov_base;
				out = ((uint8_t *) hdr_out) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);
			}

			tpacket_hdr_clone(&hdr_out->tp_h, &hdr_in->tp_h);
			fmemcpy(out, in, hdr_in->tp_h.tp_len);

			kernel_may_pull_from_tx(&hdr_out->tp_h);
			if (ctx->randomize)
				next_rnd_slot(&it_out, &tx_ring);
			else {
				it_out++;
				if (it_out >= tx_ring.layout.tp_frame_nr)
					it_out = 0;
			}

			show_frame_hdr(hdr_in, ctx->print_mode);

			dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
					      ctx->link_type, ctx->print_mode);

			if (frame_count_max != 0) {
				if (frame_count >= frame_count_max) {
					sigint = 1;
					break;
				}
			}

			next:

			kernel_may_pull_from_rx(&hdr_in->tp_h);

			it_in++;
			if (it_in >= rx_ring.layout.tp_frame_nr)
				it_in = 0;

			if (unlikely(sigint == 1))
				goto out;
		}

		poll(&rx_poll, 1, -1);
	}

	out:

	timer_purge();

	sock_rx_net_stats(rx_sock, 0);

	bpf_release(&bpf_ops);

	dissector_cleanup_all();

	destroy_tx_ring(tx_sock, &tx_ring);
	destroy_rx_ring(rx_sock, &rx_ring);

	if (ctx->promiscuous)
		leave_promiscuous_mode(ctx->device_in, ifflags);

	close(tx_sock);
	close(rx_sock);
}
Ejemplo n.º 26
0
int main(int argc, char **argv)
{
	bool slow = false, invoke_cpp = false, reseed = true;
	int c, opt_index, i, j, vals[4] = {0}, irq;
	char *confname = NULL, *ptr;
	unsigned long cpus_tmp, orig_num = 0;
	unsigned long long tx_packets, tx_bytes;
	struct ctx ctx;

	fmemset(&ctx, 0, sizeof(ctx));
	ctx.cpus = get_number_cpus_online();
	ctx.uid = getuid();
	ctx.gid = getgid();

	while ((c = getopt_long(argc, argv, short_options, long_options,
				&opt_index)) != EOF) {
		switch (c) {
		case 'h':
			help();
			break;
		case 'v':
			version();
			break;
		case 'e':
			example();
			break;
		case 'p':
			invoke_cpp = true;
			break;
		case 'V':
			ctx.verbose = true;
			break;
		case 'P':
			cpus_tmp = strtoul(optarg, NULL, 0);
			if (cpus_tmp > 0 && cpus_tmp < ctx.cpus)
				ctx.cpus = cpus_tmp;
			break;
		case 'd':
		case 'o':
			ctx.device = xstrndup(optarg, IFNAMSIZ);
			break;
		case 'r':
			ctx.rand = true;
			break;
		case 's':
			slow = true;
			ctx.cpus = 1;
			ctx.smoke_test = true;
			ctx.rhost = xstrdup(optarg);
			break;
		case 'R':
			ctx.rfraw = true;
			break;
		case 'J':
			ctx.jumbo_support = true;
			break;
		case 'c':
		case 'i':
			confname = xstrdup(optarg);
			if (!strncmp("-", confname, strlen("-")))
				ctx.cpus = 1;
			break;
		case 'u':
			ctx.uid = strtoul(optarg, NULL, 0);
			ctx.enforce = true;
			break;
		case 'g':
			ctx.gid = strtoul(optarg, NULL, 0);
			ctx.enforce = true;
			break;
		case 'k':
			ctx.kpull = strtoul(optarg, NULL, 0);
			break;
		case 'E':
			seed = strtoul(optarg, NULL, 0);
			reseed = false;
			break;
		case 'n':
			orig_num = strtoul(optarg, NULL, 0);
			ctx.num = orig_num;
			break;
		case 't':
			slow = true;
			ctx.gap = strtoul(optarg, NULL, 0);
			if (ctx.gap > 0)
				/* Fall back to single core to not
				 * mess up correct timing. We are slow
				 * anyway!
				 */
				ctx.cpus = 1;
			break;
		case 'S':
			ptr = optarg;
			ctx.reserve_size = 0;

			for (j = i = strlen(optarg); i > 0; --i) {
				if (!isdigit(optarg[j - i]))
					break;
				ptr++;
			}

			if (!strncmp(ptr, "KiB", strlen("KiB")))
				ctx.reserve_size = 1 << 10;
			else if (!strncmp(ptr, "MiB", strlen("MiB")))
				ctx.reserve_size = 1 << 20;
			else if (!strncmp(ptr, "GiB", strlen("GiB")))
				ctx.reserve_size = 1 << 30;
			else
				panic("Syntax error in ring size param!\n");
			*ptr = 0;

			ctx.reserve_size *= strtol(optarg, NULL, 0);
			break;
		case '?':
			switch (optopt) {
			case 'd':
			case 'c':
			case 'n':
			case 'S':
			case 's':
			case 'P':
			case 'o':
			case 'E':
			case 'i':
			case 'k':
			case 'u':
			case 'g':
			case 't':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					printf("Unknown option character `0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (argc < 5)
		help();
	if (ctx.device == NULL)
		panic("No networking device given!\n");
	if (confname == NULL)
		panic("No configuration file given!\n");
	if (device_mtu(ctx.device) == 0)
		panic("This is no networking device!\n");

	register_signal(SIGINT, signal_handler);
	register_signal(SIGHUP, signal_handler);
	register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);

	set_system_socket_memory(vals, array_size(vals));
	xlockme();

	if (ctx.rfraw) {
		ctx.device_trans = xstrdup(ctx.device);
		xfree(ctx.device);

		enter_rfmon_mac80211(ctx.device_trans, &ctx.device);
		sleep(0);
	}

	irq = device_irq_number(ctx.device);
	device_set_irq_affinity_list(irq, 0, ctx.cpus - 1);

	stats = setup_shared_var(ctx.cpus);

	for (i = 0; i < ctx.cpus; i++) {
		pid_t pid = fork();

		switch (pid) {
		case 0:
			if (reseed)
				seed = generate_srand_seed();
			srand(seed);

			cpu_affinity(i);
			main_loop(&ctx, confname, slow, i, invoke_cpp, orig_num);

			goto thread_out;
		case -1:
			panic("Cannot fork processes!\n");
		}
	}

	for (i = 0; i < ctx.cpus; i++) {
		int status;

		wait(&status);
		if (WEXITSTATUS(status) == EXIT_FAILURE)
			die();
	}

	if (ctx.rfraw)
		leave_rfmon_mac80211(ctx.device_trans, ctx.device);

	reset_system_socket_memory(vals, array_size(vals));

	for (i = 0, tx_packets = tx_bytes = 0; i < ctx.cpus; i++) {
		while ((__get_state(i) & CPU_STATS_STATE_RES) == 0)
			sched_yield();

		tx_packets += stats[i].tx_packets;
		tx_bytes   += stats[i].tx_bytes;
	}

	fflush(stdout);
	printf("\n");
	printf("\r%12llu packets outgoing\n", tx_packets);
	printf("\r%12llu bytes outgoing\n", tx_bytes);
	for (i = 0; i < ctx.cpus; i++) {
		printf("\r%12lu sec, %lu usec on CPU%d (%llu packets)\n",
		       stats[i].tv_sec, stats[i].tv_usec, i,
		       stats[i].tx_packets);
	}

thread_out:
	xunlockme();
	destroy_shared_var(stats, ctx.cpus);
	device_restore_irq_affinity_list();

	free(ctx.device);
	free(ctx.device_trans);
	free(ctx.rhost);
	free(confname);

	return 0;
}
Ejemplo n.º 27
0
static void xmit_slowpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_num)
{
	int ret, icmp_sock = -1;
	unsigned long num = 1, i = 0;
	struct timeval start, end, diff;
	unsigned long long tx_bytes = 0, tx_packets = 0;
	struct packet_dyn *pktd;
	struct sockaddr_ll saddr = {
		.sll_family = PF_PACKET,
		.sll_halen = ETH_ALEN,
		.sll_ifindex = device_ifindex(ctx->device),
	};

	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	if (ctx->smoke_test)
		icmp_sock = xmit_smoke_setup(ctx);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0) && likely(num > 0) && likely(plen > 0)) {
		pktd = &packet_dyn[i];
		if (pktd->clen + pktd->rlen + pktd->slen) {
			apply_counter(i);
			apply_randomizer(i);
			apply_csum16(i);
		}
retry:
		ret = sendto(sock, packets[i].payload, packets[i].len, 0,
			     (struct sockaddr *) &saddr, sizeof(saddr));
		if (unlikely(ret < 0)) {
			if (errno == ENOBUFS) {
				sched_yield();
				goto retry;
			}

			panic("Sendto error: %s!\n", strerror(errno));
		}

		tx_bytes += packets[i].len;
		tx_packets++;

		if (ctx->smoke_test) {
			ret = xmit_smoke_probe(icmp_sock, ctx);
			if (unlikely(ret < 0)) {
				printf("%sSmoke test alert:%s\n", colorize_start(bold), colorize_end());
				printf("  Remote host seems to be unresponsive to ICMP probes!\n");
				printf("  Last instance was packet%lu, seed:%u, trafgen snippet:\n\n",
				       i, seed);

				dump_trafgen_snippet(packets[i].payload, packets[i].len);
				break;
			}
		}

		if (!ctx->rand) {
			i++;
			if (i >= plen)
				i = 0;
		} else
			i = rand() % plen;

		if (ctx->num > 0)
			num--;

		if (ctx->gap > 0)
			usleep(ctx->gap);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (ctx->smoke_test)
		close(icmp_sock);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}

static void xmit_fastpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_num)
{
	int ifindex = device_ifindex(ctx->device);
	uint8_t *out = NULL;
	unsigned int it = 0;
	unsigned long num = 1, i = 0, size;
	struct ring tx_ring;
	struct frame_map *hdr;
	struct timeval start, end, diff;
	struct packet_dyn *pktd;
	unsigned long long tx_bytes = 0, tx_packets = 0;

	fmemset(&tx_ring, 0, sizeof(tx_ring));

	size = ring_size(ctx->device, ctx->reserve_size);

	set_sock_prio(sock, 512);
	set_packet_loss_discard(sock);

	setup_tx_ring_layout(sock, &tx_ring, size, ctx->jumbo_support);
	create_tx_ring(sock, &tx_ring, ctx->verbose);
	mmap_tx_ring(sock, &tx_ring);
	alloc_tx_ring_frames(sock, &tx_ring);
	bind_tx_ring(sock, &tx_ring, ifindex);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (ctx->kpull)
		interval = ctx->kpull;
	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	set_itimer_interval_value(&itimer, 0, interval);
	setitimer(ITIMER_REAL, &itimer, NULL); 

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0) && likely(num > 0) && likely(plen > 0)) {
		while (user_may_pull_from_tx(tx_ring.frames[it].iov_base) && likely(num > 0)) {
			hdr = tx_ring.frames[it].iov_base;
			out = ((uint8_t *) hdr) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);

			hdr->tp_h.tp_snaplen = packets[i].len;
			hdr->tp_h.tp_len = packets[i].len;

			pktd = &packet_dyn[i];
			if (pktd->clen + pktd->rlen + pktd->slen) {
				apply_counter(i);
				apply_randomizer(i);
				apply_csum16(i);
			}

			fmemcpy(out, packets[i].payload, packets[i].len);

			tx_bytes += packets[i].len;
			tx_packets++;

			if (!ctx->rand) {
				i++;
				if (i >= plen)
					i = 0;
			} else
				i = rand() % plen;

			kernel_may_pull_from_tx(&hdr->tp_h);

			it++;
			if (it >= tx_ring.layout.tp_frame_nr)
				it = 0;

			if (ctx->num > 0)
				num--;

			if (unlikely(sigint == 1))
				break;
		}
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	timer_purge();

	destroy_tx_ring(sock, &tx_ring);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}
Ejemplo n.º 28
0
static int xmit_smoke_probe(int icmp_sock, struct ctx *ctx)
{
	int ret, i, j = 0, probes = 100;
	short ident, cnt = 1, idstore[probes];
	uint8_t outpack[512], *data;
	struct icmphdr *icmp;
	struct iphdr *ip;
	size_t len = sizeof(*icmp) + 56;
	struct sockaddr_in from;
	socklen_t from_len;
	struct pollfd fds = {
		.fd = icmp_sock,
		.events = POLLIN,
	};

	fmemset(idstore, 0, sizeof(idstore));
	while (probes-- > 0) {
		while ((ident = htons((short) rand())) == 0)
			sleep(0);
		idstore[j++] = ident;

		memset(outpack, 0, sizeof(outpack));
		icmp = (void *) outpack;
		icmp->type = ICMP_ECHO;
		icmp->un.echo.id = ident;
		icmp->un.echo.sequence = htons(cnt++);

		data = ((uint8_t *) outpack + sizeof(*icmp));
		for (i = 0; i < 56; ++i)
			data[i] = (uint8_t) rand();

		icmp->checksum = csum((unsigned short *) outpack,
				      len / sizeof(unsigned short));

		ret = sendto(icmp_sock, outpack, len, MSG_DONTWAIT,
			     (struct sockaddr *) &ctx->dest, sizeof(ctx->dest));
		if (unlikely(ret != len))
			panic("Cannot send out probe: %s!\n", strerror(errno));

		ret = poll(&fds, 1, 50);
		if (ret < 0)
			panic("Poll failed!\n");

		if (fds.revents & POLLIN) {
			ret = recvfrom(icmp_sock, outpack, sizeof(outpack), 0,
				       (struct sockaddr *) &from, &from_len);
			if (unlikely(ret <= 0))
				panic("Probe receive failed!\n");
			if (unlikely(from_len != sizeof(ctx->dest)))
				continue;
			if (unlikely(memcmp(&from, &ctx->dest, sizeof(ctx->dest))))
				continue;
			if (unlikely(ret < sizeof(*ip) + sizeof(*icmp)))
				continue;
			ip = (void *) outpack;
			if (unlikely(ip->ihl * 4 + sizeof(*icmp) > ret))
				continue;
			icmp = (void *) outpack + ip->ihl * 4;
			for (i = 0; i < array_size(idstore); ++i) {
				if (unlikely(icmp->un.echo.id != idstore[i]))
					continue;
				return 0;
			}
		}
	}

	return -1;
}
Ejemplo n.º 29
0
static void enter_mode_rx_only_or_dump(struct mode *mode)
{
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	unsigned long fcnt = 0, skipped = 0;
	short ifflags = 0;
	uint8_t *packet;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;
	struct timeval start, end, diff;

	if (!device_up_and_running(mode->device_in))
		panic("Device not up and running!\n");

	sock = pf_socket();

	if (mode->rfraw) {
		mode->device_trans = xstrdup(mode->device_in);
		xfree(mode->device_in);

		enter_rfmon_mac80211(mode->device_trans, &mode->device_in);
		mode->link_type = LINKTYPE_IEEE802_11;
	}

	if (mode->dump) {
		struct stat tmp;
		fmemset(&tmp, 0, sizeof(tmp));
		ret = stat(mode->device_out, &tmp);
		if (ret < 0) {
			mode->dump_dir = 0;
			goto try_file;
		}
		mode->dump_dir = !!S_ISDIR(tmp.st_mode);
		if (mode->dump_dir) {
			fd = begin_multi_pcap_file(mode);
		} else {
try_file:
			fd = begin_single_pcap_file(mode);
		}
	}

	fmemset(&rx_ring, 0, sizeof(rx_ring));
	fmemset(&rx_poll, 0, sizeof(rx_poll));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(mode->device_in);
	size = ring_size(mode->device_in, mode->reserve_size);

	enable_kernel_bpf_jit_compiler();
	bpf_parse_rules(mode->filter, &bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	set_sockopt_hwtimestamp(sock, mode->device_in);
	setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
	create_rx_ring(sock, &rx_ring);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(&rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(mode->print_mode);

	if (mode->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(mode->device_in);
		device_bind_irq_to_cpu(mode->cpu, irq);
		printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq, 
		       mode->cpu);
	}

	if (mode->promiscuous == true) {
		ifflags = enter_promiscuous_mode(mode->device_in);
		printf("PROMISC\n");
	}

	printf("BPF:\n");
	bpf_dump_all(&bpf_ops);
	printf("MD: RX %s ", mode->dump ? pcap_ops[mode->pcap]->name : "");
	if (mode->rfraw)
		printf("802.11 raw via %s ", mode->device_in);
#ifdef _LARGEFILE64_SOURCE
	printf("lf64 ");
#endif 
	ioprio_print();
	printf("\n");

	gettimeofday(&start, NULL);

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
			hdr = rx_ring.frames[it].iov_base;
			packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
			fcnt++;

			if (mode->packet_type != PACKET_ALL)
				if (mode->packet_type != hdr->s_ll.sll_pkttype)
					goto next;
			if (unlikely(ring_frame_size(&rx_ring) <
				     hdr->tp_h.tp_snaplen)) {
				skipped++;
				goto next;
			}
			if (mode->dump) {
				struct pcap_pkthdr phdr;
				tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
				ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
									   packet, phdr.len);
				if (unlikely(ret != sizeof(phdr) + phdr.len))
					panic("Write error to pcap!\n");
			}

			show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
			dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
					      mode->link_type, mode->print_mode);

			if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
				sigint = 1;
				break;
			}
next:
			kernel_may_pull_from_rx(&hdr->tp_h);
			next_slot_prerd(&it, &rx_ring);

			if (unlikely(sigint == 1))
				break;
			if (mode->dump && next_dump) {
				struct tpacket_stats kstats;
				socklen_t slen = sizeof(kstats);
				fmemset(&kstats, 0, sizeof(kstats));
				getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
					   &kstats, &slen);
				fd = next_multi_pcap_file(mode, fd);
				next_dump = false;
				if (mode->print_mode == FNTTYPE_PRINT_NONE) {
					printf(".(+%lu/-%lu)",
					       1UL * kstats.tp_packets -
					       kstats.tp_drops -
					       skipped, 1UL * kstats.tp_drops +
					       skipped);
					fflush(stdout);
				}
			}
		}

		poll(&rx_poll, 1, -1);
		poll_error_maybe_die(sock, &rx_poll);
	}

	gettimeofday(&end, NULL);
	diff = tv_subtract(end, start);

	if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE)) {
		sock_print_net_stats(sock, skipped);
		printf("\r%12lu  sec, %lu usec in total\n", diff.tv_sec,
		       diff.tv_usec);
	} else {
		printf("\n\n");
		fflush(stdout);
	}

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);

	if (mode->promiscuous == true)
		leave_promiscuous_mode(mode->device_in, ifflags);

	if (mode->rfraw)
		leave_rfmon_mac80211(mode->device_trans, mode->device_in);

	close(sock);

	if (mode->dump) {
		if (mode->dump_dir)
			finish_multi_pcap_file(mode, fd);
		else
			finish_single_pcap_file(mode, fd);
	}
}
Ejemplo n.º 30
0
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);
	}
}