1dffd6523SWilliam A. Kennington III // Copyright 2022 Google LLC 2dffd6523SWilliam A. Kennington III // 3dffd6523SWilliam A. Kennington III // Licensed under the Apache License, Version 2.0 (the "License"); 4dffd6523SWilliam A. Kennington III // you may not use this file except in compliance with the License. 5dffd6523SWilliam A. Kennington III // You may obtain a copy of the License at 6dffd6523SWilliam A. Kennington III // 7dffd6523SWilliam A. Kennington III // http://www.apache.org/licenses/LICENSE-2.0 8dffd6523SWilliam A. Kennington III // 9dffd6523SWilliam A. Kennington III // Unless required by applicable law or agreed to in writing, software 10dffd6523SWilliam A. Kennington III // distributed under the License is distributed on an "AS IS" BASIS, 11dffd6523SWilliam A. Kennington III // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12dffd6523SWilliam A. Kennington III // See the License for the specific language governing permissions and 13dffd6523SWilliam A. Kennington III // limitations under the License. 14dffd6523SWilliam A. Kennington III 15dffd6523SWilliam A. Kennington III #include <fmt/format.h> 16dffd6523SWilliam A. Kennington III 17dffd6523SWilliam A. Kennington III #include <sdeventplus/event.hpp> 18dffd6523SWilliam A. Kennington III #include <sdeventplus/source/io.hpp> 19dffd6523SWilliam A. Kennington III #include <stdplus/fd/create.hpp> 20dffd6523SWilliam A. Kennington III #include <stdplus/fd/ops.hpp> 21dffd6523SWilliam A. Kennington III 225ca20ffeSYuxiao Zhang using namespace std::string_view_literals; 235ca20ffeSYuxiao Zhang 24dffd6523SWilliam A. Kennington III // A privileged port that is reserved for querying BMC DHCP completion. 25dffd6523SWilliam A. Kennington III // This is well known by the clients querying the status. 26dffd6523SWilliam A. Kennington III constexpr uint16_t kListenPort = 23; 275ca20ffeSYuxiao Zhang enum : uint8_t 285ca20ffeSYuxiao Zhang { 295ca20ffeSYuxiao Zhang DONE = 0, 305ca20ffeSYuxiao Zhang POWERCYCLE = 1, 315ca20ffeSYuxiao Zhang }; 32dffd6523SWilliam A. Kennington III 33dffd6523SWilliam A. Kennington III stdplus::ManagedFd createListener() 34dffd6523SWilliam A. Kennington III { 35dffd6523SWilliam A. Kennington III using namespace stdplus::fd; 36*2be45238SPatrick Williams auto sock = socket(SocketDomain::INet6, SocketType::Stream, 37*2be45238SPatrick Williams SocketProto::TCP); 38dffd6523SWilliam A. Kennington III setFileFlags(sock, getFileFlags(sock).set(stdplus::fd::FileFlag::NonBlock)); 39dffd6523SWilliam A. Kennington III sockaddr_in6 addr = {}; 40dffd6523SWilliam A. Kennington III addr.sin6_family = AF_INET6; 41dffd6523SWilliam A. Kennington III addr.sin6_port = htons(kListenPort); 42dffd6523SWilliam A. Kennington III bind(sock, addr); 43dffd6523SWilliam A. Kennington III listen(sock, 10); 44dffd6523SWilliam A. Kennington III return sock; 45dffd6523SWilliam A. Kennington III } 46dffd6523SWilliam A. Kennington III 475ca20ffeSYuxiao Zhang int main(int argc, char* argv[]) 48dffd6523SWilliam A. Kennington III { 495ca20ffeSYuxiao Zhang if (argc != 2) 505ca20ffeSYuxiao Zhang { 515ca20ffeSYuxiao Zhang fmt::print(stderr, "Invalid parameter count\n"); 525ca20ffeSYuxiao Zhang return 1; 535ca20ffeSYuxiao Zhang } 545ca20ffeSYuxiao Zhang 555ca20ffeSYuxiao Zhang std::vector<uint8_t> data; 565ca20ffeSYuxiao Zhang 575ca20ffeSYuxiao Zhang if (argv[1] == "POWERCYCLE"sv) 585ca20ffeSYuxiao Zhang { 595ca20ffeSYuxiao Zhang data.push_back(POWERCYCLE); 605ca20ffeSYuxiao Zhang } 615ca20ffeSYuxiao Zhang else if (argv[1] == "DONE"sv) 625ca20ffeSYuxiao Zhang { 635ca20ffeSYuxiao Zhang data.push_back(DONE); 645ca20ffeSYuxiao Zhang } 655ca20ffeSYuxiao Zhang else 665ca20ffeSYuxiao Zhang { 675ca20ffeSYuxiao Zhang fmt::print(stderr, "Invalid parameter\n"); 685ca20ffeSYuxiao Zhang return 1; 695ca20ffeSYuxiao Zhang } 705ca20ffeSYuxiao Zhang 71dffd6523SWilliam A. Kennington III try 72dffd6523SWilliam A. Kennington III { 73dffd6523SWilliam A. Kennington III auto listener = createListener(); 74dffd6523SWilliam A. Kennington III auto event = sdeventplus::Event::get_default(); 75dffd6523SWilliam A. Kennington III sdeventplus::source::IO do_accept( 76dffd6523SWilliam A. Kennington III event, listener.get(), EPOLLIN | EPOLLET, 77dffd6523SWilliam A. Kennington III [&](sdeventplus::source::IO&, int, uint32_t) { 785ca20ffeSYuxiao Zhang while (auto fd = stdplus::fd::accept(listener)) 795ca20ffeSYuxiao Zhang { 80*2be45238SPatrick Williams stdplus::fd::sendExact(*fd, data, stdplus::fd::SendFlags(0)); 815ca20ffeSYuxiao Zhang } 82dffd6523SWilliam A. Kennington III }); 83dffd6523SWilliam A. Kennington III return event.loop(); 84dffd6523SWilliam A. Kennington III } 85dffd6523SWilliam A. Kennington III catch (const std::exception& e) 86dffd6523SWilliam A. Kennington III { 87dffd6523SWilliam A. Kennington III fmt::print(stderr, "Failed: {}\n", e.what()); 88dffd6523SWilliam A. Kennington III return 1; 89dffd6523SWilliam A. Kennington III } 90dffd6523SWilliam A. Kennington III } 91