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)");
void writeEthernetHeader(const Pkt4Ptr &pkt, OutputBuffer &out_buf)
Writes ethernet frame header into a buffer.
IfaceMgr exception thrown thrown when socket opening or configuration failed.
int fallbackfd_
Fallback socket descriptor.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
size_t getMacLen() const
Returns MAC length.
Represents a single network interface.
const uint8_t * getMac() const
Returns pointer to MAC address.
void decodeEthernetHeader(InputBuffer &buf, Pkt4Ptr &pkt)
Decode the Ethernet header.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
uint16_t getHWType() const
Returns hardware type of the interface.
void writeIpUdpHeader(const Pkt4Ptr &pkt, util::OutputBuffer &out_buf)
Writes both IP and UDP header into output buffer.
uint32_t toUint32() const
Converts IPv4 address to uint32_t.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
std::string getName() const
Returns interface name.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
size_t getLength() const
Return the length of data written in the buffer.
Defines the logger used by the top-level component of kea-dhcp-ddns.
Represents DHCPv4 packet.
Hardware type that represents information from DHCPv4 packet.
uint16_t getIndex() const
Returns interface index.
The IOAddress class represents an IP addresses (version agnostic)
IfaceMgr exception thrown thrown when error occurred during sending data through socket.
Holds information about socket.
void decodeIpUdpHeader(InputBuffer &buf, Pkt4Ptr &pkt)
Decode IP and UDP header.