void bpf2_jit_free(struct bpf_program *prog)
{
	if (prog->jit_image) {
		INIT_WORK(&prog->work, bpf2_jit_free_deferred);
		schedule_work(&prog->work);
	} else {
		free_bpf_program(prog);
	}
}
static void bpf2_jit_free_deferred(struct work_struct *work)
{
	struct bpf_program *prog = container_of(work, struct bpf_program, work);
	unsigned long addr = (unsigned long)prog->jit_image & PAGE_MASK;
	struct bpf_binary_header *header = (void *)addr;

	set_memory_rw(addr, header->pages);
	module_free(NULL, header);
	free_bpf_program(prog);
}
Ejemplo n.º 3
0
int
dial(char *eth, int bufcnt)		// get us a raw connection to an interface
{
	int i, n, s;
	struct sockaddr_ll sa;
	enum { aoe_type = 0x88a2 };

	memset(&sa, 0, sizeof sa);
	s = socket(PF_PACKET, SOCK_RAW, htons(aoe_type));
	if (s == -1) {
		perror("got bad socket");
		return -1;
	}
	i = getindx(s, eth);
	sa.sll_family = AF_PACKET;
	sa.sll_protocol = htons(0x88a2);
	sa.sll_ifindex = i;
	n = bind(s, (struct sockaddr *)&sa, sizeof sa);
	if (n == -1) {
		perror("bind funky");
		return -1;
	}

	struct bpf_program {
		ulong bf_len;
		void *bf_insns;
	} *bpf_program = create_bpf_program(shelf, slot);
	setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, bpf_program, sizeof(*bpf_program));
	free_bpf_program(bpf_program);

	n = bufcnt * getmtu(s, eth);
	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n)) < 0)
		perror("setsockopt SOL_SOCKET, SO_SNDBUF");
	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) < 0)
		perror("setsockopt SOL_SOCKET, SO_RCVBUF");

	return s;
}
Ejemplo n.º 4
0
int
dial(char *eth, int bufcnt)
{
	char m;
	int fd = -1;
	struct bpf_version bv;
	u_int v;
	unsigned bufsize, linktype;
	char device[sizeof BPF_DEV];
	struct ifreq ifr;

	struct bpf_program *bpf_program = create_bpf_program(shelf, slot);
	
	strncpy(device, BPF_DEV, sizeof BPF_DEV);

	/* find a bpf device we can use, check /dev/bpf[0-9] */
	for (m = '0'; m <= '9'; m++) {
		device[sizeof(BPF_DEV)-2] = m;

		if ((fd = open(device, O_RDWR)) > 0)
			break;
	}

	if (fd < 0) {
		perror("open");
		return -1;
	}

	if (ioctl(fd, BIOCVERSION, &bv) < 0) {
		perror("BIOCVERSION");
		goto bad;
	}

	if (bv.bv_major != BPF_MAJOR_VERSION ||
	    bv.bv_minor < BPF_MINOR_VERSION) {
		fprintf(stderr,
			"kernel bpf filter out of date\n");
		goto bad;
	}

	/*
	 * Try finding a good size for the buffer; 65536 may be too
	 * big, so keep cutting it in half until we find a size
	 * that works, or run out of sizes to try.
	 *
	 */
	for (v = 65536; v != 0; v >>= 1) {
		(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);

		(void)strncpy(ifr.ifr_name, eth,
			sizeof(ifr.ifr_name));
		if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
			break;  /* that size worked; we're done */

		if (errno != ENOBUFS) {
			fprintf(stderr, "BIOCSETIF: %s: %s\n",
					eth, strerror(errno));
			goto bad;
		}
	}
	if (v == 0) {
		fprintf(stderr, 
			"BIOCSBLEN: %s: No buffer size worked\n", eth);
		goto bad;
	}

	/* Allocate memory for the packet buffer */
	pktbufsz = v;
	if ((pktbuf = malloc(pktbufsz)) == NULL) {
		perror("malloc");
		goto bad;
	}

	/* Don't wait for buffer to be full or timeout */
	v = 1;
	if (ioctl(fd, BIOCIMMEDIATE, &v) < 0) {
		perror("BIOCIMMEDIATE");
		goto bad;
	}

	/* Only read incoming packets */
	v = 0;
	if (ioctl(fd, BIOCSSEESENT, &v) < 0) {
		perror("BIOCSSEESENT");
		goto bad;
	}

	/* Don't complete ethernet hdr */
	v = 1;
	if (ioctl(fd, BIOCSHDRCMPLT, &v) < 0) {
		perror("BIOCSHDRCMPLT");
		goto bad;
	}

	/* Get the data link layer type. */
	if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
		perror("BIOCGDLT");
		goto bad;
	}
	linktype = v;

	/* Get the filter buf size */
	if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
		perror("BIOCGBLEN");
		goto bad;
	}
	bufsize = v;

	if (ioctl(fd, BIOCSETF, (caddr_t)bpf_program) < 0) {
		perror("BIOSETF");
		goto bad;
	} 

	free_bpf_program(bpf_program);
	return(fd);

bad:
	free_bpf_program(bpf_program);
	close(fd);
	return(-1);
}