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 <sdeventplus/event.hpp> 16dffd6523SWilliam A. Kennington III #include <sdeventplus/source/io.hpp> 17dffd6523SWilliam A. Kennington III #include <stdplus/fd/create.hpp> 18dffd6523SWilliam A. Kennington III #include <stdplus/fd/ops.hpp> 19*253e6463SWilly Tu #include <stdplus/print.hpp> 20dffd6523SWilliam A. Kennington III 215ca20ffeSYuxiao Zhang using namespace std::string_view_literals; 225ca20ffeSYuxiao Zhang 23dffd6523SWilliam A. Kennington III // A privileged port that is reserved for querying BMC DHCP completion. 24dffd6523SWilliam A. Kennington III // This is well known by the clients querying the status. 25dffd6523SWilliam A. Kennington III constexpr uint16_t kListenPort = 23; 265ca20ffeSYuxiao Zhang enum : uint8_t 275ca20ffeSYuxiao Zhang { 285ca20ffeSYuxiao Zhang DONE = 0, 295ca20ffeSYuxiao Zhang POWERCYCLE = 1, 305ca20ffeSYuxiao Zhang }; 31dffd6523SWilliam A. Kennington III 32dffd6523SWilliam A. Kennington III stdplus::ManagedFd createListener() 33dffd6523SWilliam A. Kennington III { 34dffd6523SWilliam A. Kennington III using namespace stdplus::fd; 352be45238SPatrick Williams auto sock = socket(SocketDomain::INet6, SocketType::Stream, 362be45238SPatrick Williams SocketProto::TCP); 37dffd6523SWilliam A. Kennington III setFileFlags(sock, getFileFlags(sock).set(stdplus::fd::FileFlag::NonBlock)); 38dffd6523SWilliam A. Kennington III sockaddr_in6 addr = {}; 39dffd6523SWilliam A. Kennington III addr.sin6_family = AF_INET6; 40dffd6523SWilliam A. Kennington III addr.sin6_port = htons(kListenPort); 41dffd6523SWilliam A. Kennington III bind(sock, addr); 42dffd6523SWilliam A. Kennington III listen(sock, 10); 43dffd6523SWilliam A. Kennington III return sock; 44dffd6523SWilliam A. Kennington III } 45dffd6523SWilliam A. Kennington III 465ca20ffeSYuxiao Zhang int main(int argc, char* argv[]) 47dffd6523SWilliam A. Kennington III { 485ca20ffeSYuxiao Zhang if (argc != 2) 495ca20ffeSYuxiao Zhang { 50*253e6463SWilly Tu stdplus::println(stderr, "Invalid parameter count"); 515ca20ffeSYuxiao Zhang return 1; 525ca20ffeSYuxiao Zhang } 535ca20ffeSYuxiao Zhang 545ca20ffeSYuxiao Zhang std::vector<uint8_t> data; 555ca20ffeSYuxiao Zhang 565ca20ffeSYuxiao Zhang if (argv[1] == "POWERCYCLE"sv) 575ca20ffeSYuxiao Zhang { 585ca20ffeSYuxiao Zhang data.push_back(POWERCYCLE); 595ca20ffeSYuxiao Zhang } 605ca20ffeSYuxiao Zhang else if (argv[1] == "DONE"sv) 615ca20ffeSYuxiao Zhang { 625ca20ffeSYuxiao Zhang data.push_back(DONE); 635ca20ffeSYuxiao Zhang } 645ca20ffeSYuxiao Zhang else 655ca20ffeSYuxiao Zhang { 66*253e6463SWilly Tu stdplus::println(stderr, "Invalid parameter"); 675ca20ffeSYuxiao Zhang return 1; 685ca20ffeSYuxiao Zhang } 695ca20ffeSYuxiao Zhang 70dffd6523SWilliam A. Kennington III try 71dffd6523SWilliam A. Kennington III { 72dffd6523SWilliam A. Kennington III auto listener = createListener(); 73dffd6523SWilliam A. Kennington III auto event = sdeventplus::Event::get_default(); 74dffd6523SWilliam A. Kennington III sdeventplus::source::IO do_accept( 75dffd6523SWilliam A. Kennington III event, listener.get(), EPOLLIN | EPOLLET, 76dffd6523SWilliam A. Kennington III [&](sdeventplus::source::IO&, int, uint32_t) { 775ca20ffeSYuxiao Zhang while (auto fd = stdplus::fd::accept(listener)) 785ca20ffeSYuxiao Zhang { 792be45238SPatrick Williams stdplus::fd::sendExact(*fd, data, stdplus::fd::SendFlags(0)); 805ca20ffeSYuxiao Zhang } 81dffd6523SWilliam A. Kennington III }); 82dffd6523SWilliam A. Kennington III return event.loop(); 83dffd6523SWilliam A. Kennington III } 84dffd6523SWilliam A. Kennington III catch (const std::exception& e) 85dffd6523SWilliam A. Kennington III { 86*253e6463SWilly Tu stdplus::println(stderr, "Failed: {}", e.what()); 87dffd6523SWilliam A. Kennington III return 1; 88dffd6523SWilliam A. Kennington III } 89dffd6523SWilliam A. Kennington III } 90