blob: df0c4fc6e954557975b2a376798f0be97bc049a2 [file] [log] [blame]
William A. Kennington III7d6fa422021-02-08 17:04:02 -08001#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
15namespace ncsi
16{
17
18int 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
25int 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 */
50struct 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
55struct sock_fprog vlan_remove_bpf = {
56 std::size(vlan_remove_code),
57 vlan_remove_code,
58};
59
60int SockIO::filter_vlans()
61{
62 return setsockopt(sockfd_, SOL_SOCKET, SO_ATTACH_FILTER, &vlan_remove_bpf,
63 sizeof(vlan_remove_bpf));
64}
65
66int 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