15 #include <net/ethernet.h>
16 #include <linux/filter.h>
17 #include <linux/if_ether.h>
18 #include <linux/if_packet.h>
46 struct sock_filter dhcp_sock_filter [] = {
53 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, ETHERNET_PACKET_TYPE_OFFSET),
55 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 11),
61 BPF_STMT(BPF_LD + BPF_B + BPF_ABS,
62 ETHERNET_HEADER_LEN + IP_PROTO_TYPE_OFFSET),
64 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 9),
72 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, ETHERNET_HEADER_LEN + IP_FLAGS_OFFSET),
74 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 7, 0),
84 BPF_STMT(BPF_LD + BPF_W + BPF_ABS,
85 ETHERNET_HEADER_LEN + IP_DEST_ADDR_OFFSET),
88 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0xffffffff, 1, 0),
92 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x00000000, 0, 4),
98 BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, ETHERNET_HEADER_LEN),
106 BPF_STMT(BPF_LD + BPF_H + BPF_IND, ETHERNET_HEADER_LEN + UDP_DEST_PORT),
113 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP4_SERVER_PORT, 0, 1),
117 BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
121 BPF_STMT(BPF_RET + BPF_K, 0),
132 PktFilterLPF::openSocket(
Iface& iface,
134 const uint16_t port,
const bool,
141 int fallback = openFallbackSocket(addr, port);
144 int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
151 if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
155 <<
" on the socket " << sock);
161 struct sock_fprog filter_program;
162 memset(&filter_program, 0,
sizeof(filter_program));
164 filter_program.filter = dhcp_sock_filter;
165 filter_program.len =
sizeof(dhcp_sock_filter) /
sizeof(
struct sock_filter);
170 dhcp_sock_filter[8].k = addr.
toUint32();
173 dhcp_sock_filter[11].k = port;
175 if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter_program,
176 sizeof(filter_program)) < 0) {
180 <<
" on the socket " << sock);
183 struct sockaddr_ll sa;
184 memset(&sa, 0,
sizeof(sockaddr_ll));
185 sa.sll_family = AF_PACKET;
192 if (bind(sock,
reinterpret_cast<const struct sockaddr*
>(&sa),
197 <<
"' to interface '" << iface.
getName() <<
"'");
200 return (
SocketInfo(addr, port, sock, fallback));
206 uint8_t raw_buf[IfaceMgr::RCVBUFSIZE];
223 datalen = recv(socket_info.
fallbackfd_, raw_buf,
sizeof(raw_buf), 0);
224 }
while (datalen > 0);
228 int data_len = read(socket_info.
sockfd_, raw_buf,
sizeof(raw_buf));
259 std::vector<uint8_t> dhcp_buf;
268 pkt->setIface(iface.
getName());
269 pkt->setLocalAddr(dummy_pkt->getLocalAddr());
270 pkt->setRemoteAddr(dummy_pkt->getRemoteAddr());
271 pkt->setLocalPort(dummy_pkt->getLocalPort());
272 pkt->setRemotePort(dummy_pkt->getRemotePort());
273 pkt->setLocalHWAddr(dummy_pkt->getLocalHWAddr());
274 pkt->setRemoteHWAddr(dummy_pkt->getRemoteHWAddr());
280 PktFilterLPF::send(
const Iface& iface, uint16_t sockfd,
const Pkt4Ptr& pkt) {
292 pkt->setLocalHWAddr(hwaddr);
305 buf.
writeData(pkt->getBuffer().getData(), pkt->getBuffer().getLength());
308 memset(&sa, 0x0,
sizeof(sa));
309 sa.sll_family = AF_PACKET;
311 sa.sll_protocol = htons(ETH_P_IP);
315 reinterpret_cast<const struct sockaddr*
>(&sa),
316 sizeof(sockaddr_ll));
319 << errno <<
" (check errno.h)");