xref: /openbmc/google-misc/acpi-power-state-daemon/subprojects/ncsid/src/ncsi_sockio.cpp (revision 1285115c16180bd28a3cfe79d9db8d10c84fe2ed)
1*1285115cSWilliam A. Kennington III // Copyright 2021 Google LLC
2*1285115cSWilliam A. Kennington III //
3*1285115cSWilliam A. Kennington III // Licensed under the Apache License, Version 2.0 (the "License");
4*1285115cSWilliam A. Kennington III // you may not use this file except in compliance with the License.
5*1285115cSWilliam A. Kennington III // You may obtain a copy of the License at
6*1285115cSWilliam A. Kennington III //
7*1285115cSWilliam A. Kennington III //      http://www.apache.org/licenses/LICENSE-2.0
8*1285115cSWilliam A. Kennington III //
9*1285115cSWilliam A. Kennington III // Unless required by applicable law or agreed to in writing, software
10*1285115cSWilliam A. Kennington III // distributed under the License is distributed on an "AS IS" BASIS,
11*1285115cSWilliam A. Kennington III // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*1285115cSWilliam A. Kennington III // See the License for the specific language governing permissions and
13*1285115cSWilliam A. Kennington III // limitations under the License.
14*1285115cSWilliam A. Kennington III 
15*1285115cSWilliam A. Kennington III #include "ncsi_sockio.h"
16*1285115cSWilliam A. Kennington III 
17*1285115cSWilliam A. Kennington III #include "common_defs.h"
18*1285115cSWilliam A. Kennington III #include "net_iface.h"
19*1285115cSWilliam A. Kennington III 
20*1285115cSWilliam A. Kennington III #include <linux/filter.h>
21*1285115cSWilliam A. Kennington III #include <netinet/in.h>
22*1285115cSWilliam A. Kennington III #include <poll.h>
23*1285115cSWilliam A. Kennington III #include <sys/socket.h>
24*1285115cSWilliam A. Kennington III #include <sys/types.h>
25*1285115cSWilliam A. Kennington III 
26*1285115cSWilliam A. Kennington III #include <cstdio>
27*1285115cSWilliam A. Kennington III #include <cstring>
28*1285115cSWilliam A. Kennington III 
29*1285115cSWilliam A. Kennington III namespace ncsi
30*1285115cSWilliam A. Kennington III {
31*1285115cSWilliam A. Kennington III 
32*1285115cSWilliam A. Kennington III int SockIO::init()
33*1285115cSWilliam A. Kennington III {
34*1285115cSWilliam A. Kennington III     RETURN_IF_ERROR(sockfd_ = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)),
35*1285115cSWilliam A. Kennington III                     "ncsi::SockIO::init() failed");
36*1285115cSWilliam A. Kennington III     return 0;
37*1285115cSWilliam A. Kennington III }
38*1285115cSWilliam A. Kennington III 
39*1285115cSWilliam A. Kennington III int SockIO::bind_to_iface(const net::IFaceBase& iface)
40*1285115cSWilliam A. Kennington III {
41*1285115cSWilliam A. Kennington III     iface.set_sock_flags(sockfd_, IFF_PROMISC);
42*1285115cSWilliam A. Kennington III 
43*1285115cSWilliam A. Kennington III     std::memset(&sock_addr_, 0, sizeof(sock_addr_));
44*1285115cSWilliam A. Kennington III 
45*1285115cSWilliam A. Kennington III     sock_addr_.sll_family = AF_PACKET;
46*1285115cSWilliam A. Kennington III     sock_addr_.sll_protocol = htons(ETH_P_ALL);
47*1285115cSWilliam A. Kennington III 
48*1285115cSWilliam A. Kennington III     RETURN_IF_ERROR(iface.bind_sock(sockfd_, &sock_addr_),
49*1285115cSWilliam A. Kennington III                     "ncsi::SockIO::bind_to_iface failed");
50*1285115cSWilliam A. Kennington III 
51*1285115cSWilliam A. Kennington III     return 0;
52*1285115cSWilliam A. Kennington III }
53*1285115cSWilliam A. Kennington III 
54*1285115cSWilliam A. Kennington III /**
55*1285115cSWilliam A. Kennington III  * Drops VLAN tagged packets from a socket
56*1285115cSWilliam A. Kennington III  *
57*1285115cSWilliam A. Kennington III  * ld vlant
58*1285115cSWilliam A. Kennington III  * jneq #0, drop
59*1285115cSWilliam A. Kennington III  * ld proto
60*1285115cSWilliam A. Kennington III  * jneq #0x88f8, drop
61*1285115cSWilliam A. Kennington III  * ret #-1
62*1285115cSWilliam A. Kennington III  * drop: ret #0
63*1285115cSWilliam A. Kennington III  */
64*1285115cSWilliam A. Kennington III struct sock_filter vlan_remove_code[] = {
65*1285115cSWilliam A. Kennington III     {0x20, 0, 0, 0xfffff02c}, {0x15, 0, 3, 0x00000000},
66*1285115cSWilliam A. Kennington III     {0x20, 0, 0, 0xfffff000}, {0x15, 0, 1, 0x000088f8},
67*1285115cSWilliam A. Kennington III     {0x6, 0, 0, 0xffffffff},  {0x6, 0, 0, 0x00000000}};
68*1285115cSWilliam A. Kennington III 
69*1285115cSWilliam A. Kennington III struct sock_fprog vlan_remove_bpf = {
70*1285115cSWilliam A. Kennington III     std::size(vlan_remove_code),
71*1285115cSWilliam A. Kennington III     vlan_remove_code,
72*1285115cSWilliam A. Kennington III };
73*1285115cSWilliam A. Kennington III 
74*1285115cSWilliam A. Kennington III int SockIO::filter_vlans()
75*1285115cSWilliam A. Kennington III {
76*1285115cSWilliam A. Kennington III     return setsockopt(sockfd_, SOL_SOCKET, SO_ATTACH_FILTER, &vlan_remove_bpf,
77*1285115cSWilliam A. Kennington III                       sizeof(vlan_remove_bpf));
78*1285115cSWilliam A. Kennington III }
79*1285115cSWilliam A. Kennington III 
80*1285115cSWilliam A. Kennington III int SockIO::recv(void* buf, size_t maxlen)
81*1285115cSWilliam A. Kennington III {
82*1285115cSWilliam A. Kennington III     struct pollfd sock_pollfd
83*1285115cSWilliam A. Kennington III     {
84*1285115cSWilliam A. Kennington III         sockfd_, POLLIN | POLLPRI, 0
85*1285115cSWilliam A. Kennington III     };
86*1285115cSWilliam A. Kennington III 
87*1285115cSWilliam A. Kennington III     int ret = poll(&sock_pollfd, 1, kpoll_timeout_);
88*1285115cSWilliam A. Kennington III     if (ret > 0)
89*1285115cSWilliam A. Kennington III     {
90*1285115cSWilliam A. Kennington III         return ::recv(sockfd_, buf, maxlen, 0);
91*1285115cSWilliam A. Kennington III     }
92*1285115cSWilliam A. Kennington III 
93*1285115cSWilliam A. Kennington III     return ret;
94*1285115cSWilliam A. Kennington III }
95*1285115cSWilliam A. Kennington III 
96*1285115cSWilliam A. Kennington III } // namespace ncsi
97