xref: /openbmc/google-misc/dhcp-done/subprojects/ncsid/src/ncsi_sockio.cpp (revision 7d6fa42fd19cf708de1257414bb375d5a552b722)
1 #include "ncsi_sockio.h"
2 
3 #include "common_defs.h"
4 #include "net_iface.h"
5 
6 #include <linux/filter.h>
7 #include <netinet/in.h>
8 #include <poll.h>
9 #include <sys/socket.h>
10 #include <sys/types.h>
11 
12 #include <cstdio>
13 #include <cstring>
14 
15 namespace ncsi
16 {
17 
18 int SockIO::init()
19 {
20     RETURN_IF_ERROR(sockfd_ = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)),
21                     "ncsi::SockIO::init() failed");
22     return 0;
23 }
24 
25 int SockIO::bind_to_iface(const net::IFaceBase& iface)
26 {
27     iface.set_sock_flags(sockfd_, IFF_PROMISC);
28 
29     std::memset(&sock_addr_, 0, sizeof(sock_addr_));
30 
31     sock_addr_.sll_family = AF_PACKET;
32     sock_addr_.sll_protocol = htons(ETH_P_ALL);
33 
34     RETURN_IF_ERROR(iface.bind_sock(sockfd_, &sock_addr_),
35                     "ncsi::SockIO::bind_to_iface failed");
36 
37     return 0;
38 }
39 
40 /**
41  * Drops VLAN tagged packets from a socket
42  *
43  * ld vlant
44  * jneq #0, drop
45  * ld proto
46  * jneq #0x88f8, drop
47  * ret #-1
48  * drop: ret #0
49  */
50 struct sock_filter vlan_remove_code[] = {
51     {0x20, 0, 0, 0xfffff02c}, {0x15, 0, 3, 0x00000000},
52     {0x20, 0, 0, 0xfffff000}, {0x15, 0, 1, 0x000088f8},
53     {0x6, 0, 0, 0xffffffff},  {0x6, 0, 0, 0x00000000}};
54 
55 struct sock_fprog vlan_remove_bpf = {
56     std::size(vlan_remove_code),
57     vlan_remove_code,
58 };
59 
60 int SockIO::filter_vlans()
61 {
62     return setsockopt(sockfd_, SOL_SOCKET, SO_ATTACH_FILTER, &vlan_remove_bpf,
63                       sizeof(vlan_remove_bpf));
64 }
65 
66 int SockIO::recv(void* buf, size_t maxlen)
67 {
68     struct pollfd sock_pollfd
69     {
70         sockfd_, POLLIN | POLLPRI, 0
71     };
72 
73     int ret = poll(&sock_pollfd, 1, kpoll_timeout_);
74     if (ret > 0)
75     {
76         return ::recv(sockfd_, buf, maxlen, 0);
77     }
78 
79     return ret;
80 }
81 
82 } // namespace ncsi
83