xref: /openbmc/google-misc/dhcp-done/subprojects/nemora-postd/nemorad.cpp (revision 14fe6698f5bb26245bb807eb041eaa7a3c29ac39)
1*14fe6698SNan Zhou // Copyright 2021 Google LLC
2*14fe6698SNan Zhou //
3*14fe6698SNan Zhou // Licensed under the Apache License, Version 2.0 (the "License");
4*14fe6698SNan Zhou // you may not use this file except in compliance with the License.
5*14fe6698SNan Zhou // You may obtain a copy of the License at
6*14fe6698SNan Zhou //
7*14fe6698SNan Zhou //      http://www.apache.org/licenses/LICENSE-2.0
8*14fe6698SNan Zhou //
9*14fe6698SNan Zhou // Unless required by applicable law or agreed to in writing, software
10*14fe6698SNan Zhou // distributed under the License is distributed on an "AS IS" BASIS,
11*14fe6698SNan Zhou // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*14fe6698SNan Zhou // See the License for the specific language governing permissions and
13*14fe6698SNan Zhou // limitations under the License.
14*14fe6698SNan Zhou 
15*14fe6698SNan Zhou #include "src/default_addresses.h"
16*14fe6698SNan Zhou 
17*14fe6698SNan Zhou #include "src/host_manager.hpp"
18*14fe6698SNan Zhou #include "src/nemora.hpp"
19*14fe6698SNan Zhou 
20*14fe6698SNan Zhou #include <arpa/inet.h>
21*14fe6698SNan Zhou #include <fmt/format.h>
22*14fe6698SNan Zhou 
23*14fe6698SNan Zhou #include <CLI/CLI.hpp>
24*14fe6698SNan Zhou #include <phosphor-logging/log.hpp>
25*14fe6698SNan Zhou 
26*14fe6698SNan Zhou #include <csignal>
27*14fe6698SNan Zhou #include <cstdint>
28*14fe6698SNan Zhou #include <iostream>
29*14fe6698SNan Zhou #include <regex>
30*14fe6698SNan Zhou #include <string>
31*14fe6698SNan Zhou #include <thread>
32*14fe6698SNan Zhou #include <unordered_map>
33*14fe6698SNan Zhou #include <vector>
34*14fe6698SNan Zhou 
35*14fe6698SNan Zhou using fmt::format;
36*14fe6698SNan Zhou using phosphor::logging::level;
37*14fe6698SNan Zhou using phosphor::logging::log;
38*14fe6698SNan Zhou 
39*14fe6698SNan Zhou namespace
40*14fe6698SNan Zhou {
41*14fe6698SNan Zhou volatile std::sig_atomic_t gSignalStatus;
42*14fe6698SNan Zhou }
43*14fe6698SNan Zhou 
44*14fe6698SNan Zhou void signal_handler(int signal)
45*14fe6698SNan Zhou {
46*14fe6698SNan Zhou     gSignalStatus = signal;
47*14fe6698SNan Zhou }
48*14fe6698SNan Zhou 
49*14fe6698SNan Zhou void NemoraUdpPoll(Nemora* nemora)
50*14fe6698SNan Zhou {
51*14fe6698SNan Zhou     while (!gSignalStatus)
52*14fe6698SNan Zhou     {
53*14fe6698SNan Zhou         nemora->UdpPoll();
54*14fe6698SNan Zhou     }
55*14fe6698SNan Zhou }
56*14fe6698SNan Zhou 
57*14fe6698SNan Zhou int main(int argc, char* argv[])
58*14fe6698SNan Zhou {
59*14fe6698SNan Zhou     // Init arg parser
60*14fe6698SNan Zhou     CLI::App app("gBMC-side Nemora implementation (POST-code only)");
61*14fe6698SNan Zhou 
62*14fe6698SNan Zhou     std::string udp_address_v4_str;
63*14fe6698SNan Zhou     auto* ipv4_option = app.add_option(
64*14fe6698SNan Zhou         "--udp4", udp_address_v4_str,
65*14fe6698SNan Zhou         "Target IPv4 address for UDP communication, i.e., POST streaming.",
66*14fe6698SNan Zhou         true);
67*14fe6698SNan Zhou 
68*14fe6698SNan Zhou     std::string udp_address_v6_str;
69*14fe6698SNan Zhou     auto* ipv6_option = app.add_option(
70*14fe6698SNan Zhou         "--udp6", udp_address_v6_str,
71*14fe6698SNan Zhou         "Target IPv6 address for UDP communication, i.e., POST streaming.",
72*14fe6698SNan Zhou         true);
73*14fe6698SNan Zhou 
74*14fe6698SNan Zhou     // interface is last, and required.
75*14fe6698SNan Zhou     std::string iface_name;
76*14fe6698SNan Zhou     app.add_option("interface", iface_name,
77*14fe6698SNan Zhou                    "Network interface for TCP communication. Ex: eth0")
78*14fe6698SNan Zhou         ->required();
79*14fe6698SNan Zhou 
80*14fe6698SNan Zhou     CLI11_PARSE(app, argc, argv);
81*14fe6698SNan Zhou 
82*14fe6698SNan Zhou     in_addr udp_address_v4;
83*14fe6698SNan Zhou     udp_address_v4.s_addr = htonl(DEFAULT_ADDRESSES_TARGET_IP);
84*14fe6698SNan Zhou     if (*ipv4_option &&
85*14fe6698SNan Zhou         !inet_pton(AF_INET, udp_address_v4_str.c_str(), &udp_address_v4))
86*14fe6698SNan Zhou     {
87*14fe6698SNan Zhou         std::cerr << "Invalid IPv4 address supplied: " << udp_address_v4_str
88*14fe6698SNan Zhou                   << std::endl;
89*14fe6698SNan Zhou     }
90*14fe6698SNan Zhou 
91*14fe6698SNan Zhou     // The value from default_addresses.h is designed for LWIP which EC uses,
92*14fe6698SNan Zhou     // and needs to be translated to network byte order.
93*14fe6698SNan Zhou     in6_addr udp_address_v6;
94*14fe6698SNan Zhou     uint32_t default_addr_6[4] = DEFAULT_ADDRESSES_TARGET_IP6;
95*14fe6698SNan Zhou 
96*14fe6698SNan Zhou     auto htonl_inplace = [](uint32_t& i) { i = htonl(i); };
97*14fe6698SNan Zhou     std::for_each(std::begin(default_addr_6), std::end(default_addr_6),
98*14fe6698SNan Zhou                   htonl_inplace);
99*14fe6698SNan Zhou     std::memcpy(udp_address_v6.s6_addr, default_addr_6, sizeof(default_addr_6));
100*14fe6698SNan Zhou 
101*14fe6698SNan Zhou     if (*ipv6_option &&
102*14fe6698SNan Zhou         !inet_pton(AF_INET6, udp_address_v6_str.c_str(), &udp_address_v6))
103*14fe6698SNan Zhou     {
104*14fe6698SNan Zhou         std::cerr << "Invalid IPv6 address supplied: " << udp_address_v6_str
105*14fe6698SNan Zhou                   << std::endl;
106*14fe6698SNan Zhou     }
107*14fe6698SNan Zhou 
108*14fe6698SNan Zhou     log<level::INFO>("Start Nemora...");
109*14fe6698SNan Zhou     Nemora nemora(iface_name, udp_address_v4, udp_address_v6);
110*14fe6698SNan Zhou 
111*14fe6698SNan Zhou     // Install a signal handler
112*14fe6698SNan Zhou     std::signal(SIGINT, signal_handler);
113*14fe6698SNan Zhou 
114*14fe6698SNan Zhou     std::thread udp(NemoraUdpPoll, &nemora);
115*14fe6698SNan Zhou 
116*14fe6698SNan Zhou     udp.join();
117*14fe6698SNan Zhou 
118*14fe6698SNan Zhou     return EXIT_SUCCESS;
119*14fe6698SNan Zhou }
120