コード例 #1
0
#include <stdint.h>

#include "bpf-sql.h"

/* SELECT TGVENDOR,FREQ(UNIPFAGT) WHERE TGVENDOR IN (1,2,3,4) */

static struct bpf_insn bpf_insns[] = {
	/* C[0] IN (1,2,3,4) */
	BPF_STMT(BPF_LD+BPF_ABS, 0),
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 4),
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 2, 0, 3),
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 2),
	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 4, 0, 1),

	BPF_STMT(BPF_RET+BPF_K, 0),

	/* R[0] = C[0] */
	BPF_STMT(BPF_ST+BPF_REC, 0),

	BPF_STMT(BPF_LD+BPF_ABS, 1),
	BPF_STMT(BPF_ST+BPF_REC, 1),

	/* R <- G */
	BPF_STMT(BPF_MISC+BPF_LDR, 0),

	/* R[2]++ */
	BPF_STMT(BPF_LD+BPF_REC, 2),
	BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
	BPF_STMT(BPF_ST+BPF_REC, 2),

	/* G <- R */
コード例 #2
0
	BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
	/* or with X */
	BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
	/* put result into X */
	BPF_STMT(BPF_MISC| BPF_TAX, 0),

	/*
	 * Allow management frames through, this also gives us those
	 * management frames that we sent ourselves with status
	 */
	/* load the lower byte of the IEEE 802.11 frame control field */
	BPF_STMT(BPF_LD  | BPF_B | BPF_IND, 0),
	/* mask off frame type and version */
	BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
	/* accept frame if it's both 0, fall through otherwise */
	BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),

	/*
	 * TODO: add a bit to radiotap RX flags that indicates
	 * that the sending station is not associated, then
	 * add a filter here that filters on our DA and that flag
	 * to allow us to deauth frames to that bad station.
	 *
	 * For now allow all To DS data frames through.
	 */
	/* load the IEEE 802.11 frame control field */
	BPF_STMT(BPF_LD  | BPF_H | BPF_IND, 0),
	/* mask off frame type, version and DS status */
	BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
	/* accept frame if version 0, type 2 and To DS, fall through otherwise
	 */
コード例 #3
0
ファイル: lldp-network.c プロジェクト: GuillaumeSeren/systemd
int lldp_network_bind_raw_socket(int ifindex) {

        static const struct sock_filter filter[] = {
                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ethhdr, h_dest)),      /* A <- 4 bytes of destination MAC */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0180c200, 1, 0),                    /* A != 01:80:c2:00 */
                BPF_STMT(BPF_RET + BPF_K, 0),                                             /* drop packet */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_dest) + 4),  /* A <- remaining 2 bytes of destination MAC */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0000, 3, 0),                        /* A != 00:00 */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0003, 2, 0),                        /* A != 00:03 */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x000e, 1, 0),                        /* A != 00:0e */
                BPF_STMT(BPF_RET + BPF_K, 0),                                             /* drop packet */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ethhdr, h_proto)),     /* A <- protocol */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_LLDP, 1, 0),                /* A != ETHERTYPE_LLDP */
                BPF_STMT(BPF_RET + BPF_K, 0),                                             /* drop packet */
                BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1),                                 /* accept packet */
        };

        static const struct sock_fprog fprog = {
                .len = ELEMENTSOF(filter),
                .filter = (struct sock_filter*) filter,
        };

        struct packet_mreq mreq = {
                .mr_ifindex = ifindex,
                .mr_type = PACKET_MR_MULTICAST,
                .mr_alen = ETH_ALEN,
                .mr_address = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }
        };

        union sockaddr_union saddrll = {
                .ll.sll_family = AF_PACKET,
                .ll.sll_ifindex = ifindex,
        };

        _cleanup_close_ int fd = -1;
        int r;

        assert(ifindex > 0);

        fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK,
                    htobe16(ETHERTYPE_LLDP));
        if (fd < 0)
                return -errno;

        r = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
        if (r < 0)
                return -errno;

        r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
        if (r < 0)
                return -errno;

        mreq.mr_address[ETH_ALEN - 1] = 0x03;
        r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
        if (r < 0)
                return -errno;

        mreq.mr_address[ETH_ALEN - 1] = 0x0E;
        r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
        if (r < 0)
                return -errno;

        r = bind(fd, &saddrll.sa, sizeof(saddrll.ll));
        if (r < 0)
                return -errno;

        r = fd;
        fd = -1;

        return r;
}
コード例 #4
0
  // Since the fake SNP is based on a real NIC, to avoid conflict with the host NIC
  // network stack, we use a different MAC address.
  // So just change the last byte of the MAC address for the real NIC.
  //
  Mode->CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;

  return EFI_SUCCESS;
}


static struct bpf_insn mFilterInstructionTemplate[] = {
  // Load 4 bytes from the destination MAC address.
  BPF_STMT (BPF_LD + BPF_W + BPF_ABS, OFFSET_OF (ETHERNET_HEADER, DstAddr[0])),

  // Compare to first 4 bytes of fake MAC address.
  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x12345678, 0, 3 ),

  // Load remaining 2 bytes from the destination MAC address.
  BPF_STMT (BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( ETHERNET_HEADER, DstAddr[4])),

  // Compare to remaining 2 bytes of fake MAC address.
  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x9ABC, 5, 0 ),

  // Load 4 bytes from the destination MAC address.
  BPF_STMT (BPF_LD + BPF_W + BPF_ABS, OFFSET_OF (ETHERNET_HEADER, DstAddr[0])),

  // Compare to first 4 bytes of broadcast MAC address.
  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0xFFFFFFFF, 0, 2),

  // Load remaining 2 bytes from the destination MAC address.
  BPF_STMT (BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( ETHERNET_HEADER, DstAddr[4])),
コード例 #5
0
ファイル: bpf-direct.c プロジェクト: 020gzh/linux
static int install_filter(void)
{
	struct sock_filter filter[] = {
		/* Grab the system call number */
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
		/* Jump table for the allowed syscalls */
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
#ifdef __NR_sigreturn
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
#endif
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit_group, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 0, 1),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_read, 1, 0),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 3, 2),

		/* Check that read is only using stdin. */
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDIN_FILENO, 4, 0),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),

		/* Check that write is only using stdout */
		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_arg(0)),
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDOUT_FILENO, 1, 0),
		/* Trap attempts to write to stderr */
		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, STDERR_FILENO, 1, 2),

		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
	};
	struct sock_fprog prog = {
		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
		.filter = filter,
	};

	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
		perror("prctl(NO_NEW_PRIVS)");
		return 1;
	}


	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
		perror("prctl");
		return 1;
	}
	return 0;
}

#define payload(_c) (_c), sizeof((_c))
int main(int argc, char **argv)
{
	char buf[4096];
	ssize_t bytes = 0;
	if (install_emulator())
		return 1;
	if (install_filter())
		return 1;
	syscall(__NR_write, STDOUT_FILENO,
		payload("OHAI! WHAT IS YOUR NAME? "));
	bytes = syscall(__NR_read, STDIN_FILENO, buf, sizeof(buf));
	syscall(__NR_write, STDOUT_FILENO, payload("HELLO, "));
	syscall(__NR_write, STDOUT_FILENO, buf, bytes);
	syscall(__NR_write, STDERR_FILENO,
		payload("Error message going to STDERR\n"));
	return 0;
}
コード例 #6
0
ファイル: npf_bpf_comp.c プロジェクト: alexk99/npf
/*
 * npfctl_bpf_cidr: code block to match IPv4 or IPv6 CIDR.
 *
 * => IP address shall be in the network byte order.
 */
void
npfctl_bpf_cidr(npf_bpf_t *ctx, u_int opts, sa_family_t af,
    const npf_addr_t *addr, const npf_netmask_t mask)
{
	const uint32_t *awords = (const uint32_t *)addr;
	u_int nwords, length, maxmask, off;

	assert(((opts & MATCH_SRC) != 0) ^ ((opts & MATCH_DST) != 0));
	assert((mask && mask <= NPF_MAX_NETMASK) || mask == NPF_NO_NETMASK);

	switch (af) {
	case AF_INET:
		maxmask = 32;
		off = (opts & MATCH_SRC) ?
		    offsetof(struct ip, ip_src) :
		    offsetof(struct ip, ip_dst);
		nwords = sizeof(struct in_addr) / sizeof(uint32_t);
		break;
	case AF_INET6:
		maxmask = 128;
		off = (opts & MATCH_SRC) ?
		    offsetof(struct ip6_hdr, ip6_src) :
		    offsetof(struct ip6_hdr, ip6_dst);
		nwords = sizeof(struct in6_addr) / sizeof(uint32_t);
		break;
	default:
		abort();
	}

	/* Ensure address family. */
	fetch_l3(ctx, af, 0);

	length = (mask == NPF_NO_NETMASK) ? maxmask : mask;

	/* CAUTION: BPF operates in host byte-order. */
	for (u_int i = 0; i < nwords; i++) {
		const u_int woff = i * sizeof(uint32_t);
		uint32_t word = ntohl(awords[i]);
		uint32_t wordmask;

		if (length >= 32) {
			/* The mask is a full word - do not apply it. */
			wordmask = 0;
			length -= 32;
		} else if (length) {
			wordmask = 0xffffffff << (32 - length);
			length = 0;
		} else {
			/* The mask became zero - skip the rest. */
			break;
		}

		/* A <- IP address (or one word of it) */
		struct bpf_insn insns_ip[] = {
			BPF_STMT(BPF_LD+BPF_W+BPF_ABS, off + woff),
		};
		add_insns(ctx, insns_ip, __arraycount(insns_ip));

		/* A <- (A & MASK) */
		if (wordmask) {
			struct bpf_insn insns_mask[] = {
				BPF_STMT(BPF_ALU+BPF_AND+BPF_K, wordmask),
			};
			add_insns(ctx, insns_mask, __arraycount(insns_mask));
		}

		/* A == expected-IP-word ? */
		struct bpf_insn insns_cmp[] = {
			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, word, 0, JUMP_MAGIC),
		};
		add_insns(ctx, insns_cmp, __arraycount(insns_cmp));
	}

	uint32_t mwords[] = {
		(opts & MATCH_SRC) ? BM_SRC_CIDR: BM_DST_CIDR, 6,
		af, mask, awords[0], awords[1], awords[2], awords[3],
	};
	done_block(ctx, mwords, sizeof(mwords));
}
コード例 #7
0
ファイル: npf_bpf_comp.c プロジェクト: alexk99/npf
static void
fetch_l3(npf_bpf_t *ctx, sa_family_t af, u_int flags)
{
	u_int ver;

	switch (af) {
	case AF_INET:
		ver = IPVERSION;
		break;
	case AF_INET6:
		ver = IPV6_VERSION >> 4;
		break;
	case AF_UNSPEC:
		ver = 0;
		break;
	default:
		abort();
	}

	/*
	 * The memory store is populated with:
	 * - BPF_MW_IPVER: IP version (4 or 6).
	 * - BPF_MW_L4OFF: L4 header offset.
	 * - BPF_MW_L4PROTO: L4 protocol.
	 */
	if ((ctx->flags & FETCHED_L3) == 0 || (af && ctx->af == 0)) {
		const uint8_t jt = ver ? 0 : JUMP_MAGIC;
		const uint8_t jf = ver ? JUMP_MAGIC : 0;
		bool ingroup = ctx->ingroup;

		/*
		 * L3 block cannot be inserted in the middle of a group.
		 * In fact, it never is.  Check and start the group after.
		 */
		if (ingroup) {
			assert(ctx->nblocks == ctx->gblock);
			npfctl_bpf_endgroup(ctx);
		}

		/*
		 * A <- IP version; A == expected-version?
		 * If no particular version specified, check for non-zero.
		 */
		struct bpf_insn insns_af[] = {
			BPF_STMT(BPF_LD+BPF_W+BPF_MEM, BPF_MW_IPVER),
			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ver, jt, jf),
		};
		add_insns(ctx, insns_af, __arraycount(insns_af));
		ctx->flags |= FETCHED_L3;
		ctx->af = af;

		if (af) {
			uint32_t mwords[] = { BM_IPVER, 1, af };
			done_raw_block(ctx, mwords, sizeof(mwords));
		}
		if (ingroup) {
			npfctl_bpf_group(ctx);
		}

	} else if (af && af != ctx->af) {
		errx(EXIT_FAILURE, "address family mismatch");
	}

	if ((flags & X_EQ_L4OFF) != 0 && (ctx->flags & X_EQ_L4OFF) == 0) {
		/* X <- IP header length */
		struct bpf_insn insns_hlen[] = {
			BPF_STMT(BPF_LDX+BPF_MEM, BPF_MW_L4OFF),
		};
		add_insns(ctx, insns_hlen, __arraycount(insns_hlen));
		ctx->flags |= X_EQ_L4OFF;
	}
}
コード例 #8
0
ファイル: arp-util.c プロジェクト: Werkov/systemd
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
        struct sock_filter filter[] = {
                BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                         /* A <- packet length */
                BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0),           /* packet >= arp packet ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_hrd)), /* A <- header */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0),                       /* header == ethernet ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_pro)), /* A <- protocol */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0),                       /* protocol == IP ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_hln)), /* A <- hardware address length */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, sizeof(struct ether_addr), 1, 0),          /* length == sizeof(ether_addr)? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_pln)), /* A <- protocol address length */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, sizeof(struct in_addr), 1, 0),             /* length == sizeof(in_addr) ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_op)),  /* A <- operation */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 2, 0),                      /* protocol == request ? */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0),                        /* protocol == reply ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                /* Sender Hardware Address must be different from our own */
                BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne32(&eth_mac->ether_addr_octet[0])),/* A <- 4 bytes of client's MAC */
                BPF_STMT(BPF_MISC + BPF_TAX, 0),                                               /* X <- A */
                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_sha)),       /* A <- 4 bytes of SHA */
                BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                        /* A xor X */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 6),                                  /* A == 0 ? */
                BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne16(&eth_mac->ether_addr_octet[4])),/* A <- remainder of client's MAC */
                BPF_STMT(BPF_MISC + BPF_TAX, 0),                                               /* X <- A */
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, arp_sha) + 4),   /* A <- remainder of SHA */
                BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                        /* A xor X */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1),                                  /* A == 0 ? */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
                /* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
                BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)),                                  /* A <- clients IP */
                BPF_STMT(BPF_MISC + BPF_TAX, 0),                                               /* X <- A */
                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)),       /* A <- SPA */
                BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                        /* X xor A */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1),                                  /* A == 0 ? */
                BPF_STMT(BPF_RET + BPF_K, 65535),                                              /* return all */
                BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)),                                  /* A <- clients IP */
                BPF_STMT(BPF_MISC + BPF_TAX, 0),                                               /* X <- A */
                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_tpa)),       /* A <- TPA */
                BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                        /* X xor A */
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1),                                  /* A == 0 ? */
                BPF_STMT(BPF_RET + BPF_K, 65535),                                              /* return all */
                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
        };
        struct sock_fprog fprog = {
                .len = ELEMENTSOF(filter),
                .filter = (struct sock_filter*) filter
        };
        union sockaddr_union link = {
                .ll.sll_family = AF_PACKET,
                .ll.sll_protocol = htobe16(ETH_P_ARP),
                .ll.sll_ifindex = ifindex,
                .ll.sll_halen = ETH_ALEN,
                .ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
        };
        _cleanup_close_ int s = -1;
        int r;

        assert(ifindex > 0);

        s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
        if (s < 0)
                return -errno;

        r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
        if (r < 0)
                return -errno;

        r = bind(s, &link.sa, sizeof(link.ll));
        if (r < 0)
                return -errno;

        r = s;
        s = -1;

        return r;
}

static int arp_send_packet(int fd, int ifindex,
                           be32_t pa, const struct ether_addr *ha,
                           bool announce) {
        union sockaddr_union link = {
                .ll.sll_family = AF_PACKET,
                .ll.sll_protocol = htobe16(ETH_P_ARP),
                .ll.sll_ifindex = ifindex,
                .ll.sll_halen = ETH_ALEN,
                .ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
        };
        struct ether_arp arp = {
                .ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */
                .ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */
                .ea_hdr.ar_hln = ETH_ALEN, /* HLEN */
                .ea_hdr.ar_pln = sizeof(be32_t), /* PLEN */
                .ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */
        };
        int r;

        assert(fd >= 0);
        assert(pa != 0);
        assert(ha);

        memcpy(&arp.arp_sha, ha, ETH_ALEN);
        memcpy(&arp.arp_tpa, &pa, sizeof(pa));

        if (announce)
                memcpy(&arp.arp_spa, &pa, sizeof(pa));

        r = sendto(fd, &arp, sizeof(struct ether_arp), 0, &link.sa, sizeof(link.ll));
        if (r < 0)
                return -errno;

        return 0;
}

int arp_send_probe(int fd, int ifindex,
                    be32_t pa, const struct ether_addr *ha) {
        return arp_send_packet(fd, ifindex, pa, ha, false);
}

int arp_send_announcement(int fd, int ifindex,
                          be32_t pa, const struct ether_addr *ha) {
        return arp_send_packet(fd, ifindex, pa, ha, true);
}
コード例 #9
0
ファイル: isis_bpf.c プロジェクト: AsherBond/quagga
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_flags.h"
#include "isisd/isisd.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_network.h"

#include "privs.h"

extern struct zebra_privs_t isisd_privs;

struct bpf_insn llcfilter[] = {
  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN),	/* check first byte */
  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5),
  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1),
  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 3),	/* check second byte */
  BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2),
  BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1),	/* check third byte */
  BPF_STMT (BPF_RET + BPF_K, (u_int) - 1),
  BPF_STMT (BPF_RET + BPF_K, 0)
};
u_int readblen = 0;
u_char *readbuff = NULL;

/*
 * Table 9 - Architectural constants for use with ISO 8802 subnetworks
 * ISO 10589 - 8.4.8
 */
コード例 #10
0
ファイル: Utility.c プロジェクト: Emat12/NDNBlue-BlueZ
int CapsH_createBPF(char* ifname) {
    int bpf = 0;
    int i;
    char filename[11] = {0};
    
    seteuid(CapsH_euid);

    for ( i = 0; i < 99; i++ ) { /* make sure we test every bpf file */
    sprintf(filename, "/dev/bpf%i", i);
    bpf = open(filename, O_RDWR);
    if ( bpf >= 0 ) {
        printf("opened file: %s\n", filename);
        struct ifreq bound_if;
        strcpy(bound_if.ifr_name, ifname);
        /* attach to given interface */
        if ( ioctl(bpf, BIOCSETIF, &bound_if) > 0 ) {
            printf("Error binding bpf device to %s\n", ifname);
            perror("interface error");
            return -1;
        }
        printf("bound bpf to %s\n", ifname);
        
        int opt = 1;
        /* set device to nonblocking */
        if( ioctl(bpf, FIONBIO, &opt) == -1 ) {
            perror("error setting nonblockig BPF\n");
            return -1;
        }
        /* return immediately when a packet is received */
        if( ioctl( bpf, BIOCIMMEDIATE, &opt ) == -1 ) {
            perror("error setting BIOCIMMEDIATE mode\n");
            return -1;
        }
        
        /* get mac address of ifname */
        struct ifaddrs *ifap, *ifaptr;
        uint8_t thishwaddr[6];
        uint8_t* ptr;

        if ( getifaddrs(&ifap) == 0 ) {
            for ( ifaptr = ifap; ifaptr != NULL; ifaptr = ifaptr->ifa_next ) {
                if( ((ifaptr)->ifa_addr)->sa_family == AF_LINK ) {
                    if ( strcmp(ifname, ifaptr->ifa_name) == 0 ) {
                        ptr = (uint8_t*)LLADDR((struct sockaddr_dl *)(ifaptr)->ifa_addr); 
                        thishwaddr[0] = *ptr;
                        thishwaddr[1] = *(ptr+1);
                        thishwaddr[2] = *(ptr+2);
                        thishwaddr[3] = *(ptr+3);
                        thishwaddr[4] = *(ptr+4);
                        thishwaddr[5] = *(ptr+5);
                    }
                }
            }
            freeifaddrs(ifap);
        }
        else {
            printf("enable to get MAC address of %s\n", ifname);
            return -1;
        }

        /* filter by destination address, then by ether type */ 
        struct bpf_program fcode = {0};
        struct bpf_insn insns[] = {
            BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, thishwaddr[0], 0, 13),
            BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 1),
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, thishwaddr[1], 0, 11),
            BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 2),
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, thishwaddr[2], 0, 9),
            BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, thishwaddr[3], 0, 7),
            BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, thishwaddr[4], 0, 5),
            BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, thishwaddr[5], 0, 3),
                /* copy protocol value (byte offset 12 of ether frame) into accumulator register */
            BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
                /* If accumulator register is equal to LinkC_eth_proto, execute following return STMT */
                /* If not, jump to STMT that returns 0 (drop packet) */
            BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, LinkC_eth_proto, 0, 1),
            BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
            BPF_STMT(BPF_RET+BPF_K, 0),
        };  
            /* Set the filter */
        fcode.bf_len = sizeof(insns) / sizeof(struct bpf_insn);
        fcode.bf_insns = &insns[0];
        if( ioctl( bpf, BIOCSETF, &fcode ) < 0) {
            printf("error setting BPF filter\n");
            return ( -1 );
        }
        seteuid(CapsH_ruid);
        printf("bpf = %d\n", bpf);
        return bpf;
    }
}
seteuid(CapsH_ruid);
fprintf(stderr, "Error: no bpf files could be opened\n");
return -1;
}