Changeset View
Changeset View
Standalone View
Standalone View
sbin/dhclient/bpf.c
/* $OpenBSD: bpf.c,v 1.13 2004/05/05 14:28:58 deraadt Exp $ */ | /* $OpenBSD: bpf.c,v 1.13 2004/05/05 14:28:58 deraadt Exp $ */ | ||||
/* BPF socket interface code, originally contributed by Archie Cobbs. */ | /* BPF socket interface code, originally contributed by Archie Cobbs. */ | ||||
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-3-Clause | * SPDX-License-Identifier: BSD-3-Clause | ||||
* | * | ||||
* Copyright (c) 2021 Franco Fichtner <franco@opnsense.org> | |||||
* Copyright (c) 1995, 1996, 1998, 1999 | * Copyright (c) 1995, 1996, 1998, 1999 | ||||
* The Internet Software Consortium. All rights reserved. | * The Internet Software Consortium. All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* | * | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
▲ Show 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, | ||||
error("setsockopt(IP_HDRINCL): %m"); | error("setsockopt(IP_HDRINCL): %m"); | ||||
info->ufdesc = sock; | info->ufdesc = sock; | ||||
} | } | ||||
/* | /* | ||||
* Packet filter program... | * Packet filter program... | ||||
*/ | */ | ||||
static const struct bpf_insn dhcp_bpf_filter[] = { | static const struct bpf_insn dhcp_bpf_filter[] = { | ||||
/* Use relative index (0) for IP packet... */ | |||||
BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, 0), | |||||
/* | |||||
* Test whether this is a VLAN packet... | |||||
* | |||||
* In case the server packet is using a VLAN ID | |||||
* of 0, meaning an untagged priority was set, the | |||||
* response shall be read and replied to. | |||||
*/ | |||||
markj: EVL_VLID_MASK? | |||||
Done Inline Actionsnice catch, thanks franco_opnsense.org: nice catch, thanks | |||||
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 12), | |||||
Done Inline ActionsShouldn't we just drop the packet if the comparison fails? markj: Shouldn't we just drop the packet if the comparison fails? | |||||
Done Inline ActionsYes, saves time. franco_opnsense.org: Yes, saves time. | |||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_VLAN, 0, 4), | |||||
/* Test whether it has a VID of 0 */ | |||||
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14), | |||||
BPF_STMT(BPF_ALU + BPF_AND + BPF_K, EVL_VLID_MASK), | |||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 17), | |||||
/* Correct the relative index for VLAN packet (4)... */ | |||||
BPF_STMT(BPF_LDX + BPF_W + BPF_IMM, 4), | |||||
/* Make sure this is an IP packet... */ | /* Make sure this is an IP packet... */ | ||||
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), | BPF_STMT(BPF_LD + BPF_H + BPF_IND, 12), | ||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8), | BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 14), | ||||
/* Make sure it's a UDP packet... */ | /* Make sure it's a UDP packet... */ | ||||
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23), | BPF_STMT(BPF_LD + BPF_B + BPF_IND, 23), | ||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), | BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 12), | ||||
/* Make sure this isn't a fragment... */ | /* Make sure this isn't a fragment... */ | ||||
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), | BPF_STMT(BPF_LD + BPF_H + BPF_IND, 20), | ||||
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, IP_MF|IP_OFFMASK, 4, 0), | BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, IP_MF|IP_OFFMASK, 10, 0), | ||||
/* Get the IP header length... */ | /* | ||||
* Get the IP header length... | |||||
* | |||||
* To find the correct position of the IP header | |||||
* length field store the index (0 or 4) in the | |||||
* accumulator and compare it with 0. | |||||
*/ | |||||
BPF_STMT(BPF_MISC + BPF_TXA, 0), | |||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 2), | |||||
/* Store IP header length of IP packet in index. */ | |||||
Done Inline ActionsI think some more detailed comment is worth having here. It's not obvious to me what this block is doing. markj: I think some more detailed comment is worth having here. It's not obvious to me what this block… | |||||
Done Inline ActionsI did this first back in 2018 so I had to take a closer look. Comments may not be well-rounded. The biggest issue was that BPF_MSH wasn't going to the index based on variable offset through IP or VLAN situation requiring a static comparison between both cases and calculating the result moving it back. franco_opnsense.org: I did this first back in 2018 so I had to take a closer look. Comments may not be well-rounded. | |||||
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), | BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), | ||||
/* Skip over following VLAN handling instruction. */ | |||||
BPF_JUMP(BPF_JMP + BPF_JA, 1, 0, 0), | |||||
/* Store IP header length of VLAN packet in index. */ | |||||
BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 18), | |||||
/* Add IP header length to previous relative index. */ | |||||
BPF_STMT(BPF_ALU + BPF_ADD + BPF_X, 0), | |||||
/* Move result back to index to reach UDP header below. */ | |||||
BPF_STMT(BPF_MISC + BPF_TAX, 0), | |||||
/* Make sure it's to the right port... */ | /* Make sure it's to the right port... */ | ||||
BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), | BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), | ||||
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, LOCAL_PORT, 0, 1), | BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, LOCAL_PORT, 0, 1), | ||||
/* If we passed all the tests, ask for the whole packet. */ | /* If we passed all the tests, ask for the whole packet. */ | ||||
BPF_STMT(BPF_RET+BPF_K, (u_int)-1), | BPF_STMT(BPF_RET+BPF_K, (u_int)-1), | ||||
▲ Show 20 Lines • Show All 269 Lines • Show Last 20 Lines |
EVL_VLID_MASK?