1*dffd6523SWilliam A. Kennington III // Copyright 2022 Google LLC
2*dffd6523SWilliam A. Kennington III //
3*dffd6523SWilliam A. Kennington III // Licensed under the Apache License, Version 2.0 (the "License");
4*dffd6523SWilliam A. Kennington III // you may not use this file except in compliance with the License.
5*dffd6523SWilliam A. Kennington III // You may obtain a copy of the License at
6*dffd6523SWilliam A. Kennington III //
7*dffd6523SWilliam A. Kennington III //      http://www.apache.org/licenses/LICENSE-2.0
8*dffd6523SWilliam A. Kennington III //
9*dffd6523SWilliam A. Kennington III // Unless required by applicable law or agreed to in writing, software
10*dffd6523SWilliam A. Kennington III // distributed under the License is distributed on an "AS IS" BASIS,
11*dffd6523SWilliam A. Kennington III // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*dffd6523SWilliam A. Kennington III // See the License for the specific language governing permissions and
13*dffd6523SWilliam A. Kennington III // limitations under the License.
14*dffd6523SWilliam A. Kennington III 
15*dffd6523SWilliam A. Kennington III #include <fmt/format.h>
16*dffd6523SWilliam A. Kennington III 
17*dffd6523SWilliam A. Kennington III #include <sdeventplus/event.hpp>
18*dffd6523SWilliam A. Kennington III #include <sdeventplus/source/io.hpp>
19*dffd6523SWilliam A. Kennington III #include <stdplus/fd/create.hpp>
20*dffd6523SWilliam A. Kennington III #include <stdplus/fd/ops.hpp>
21*dffd6523SWilliam A. Kennington III 
22*dffd6523SWilliam A. Kennington III // A privileged port that is reserved for querying BMC DHCP completion.
23*dffd6523SWilliam A. Kennington III // This is well known by the clients querying the status.
24*dffd6523SWilliam A. Kennington III constexpr uint16_t kListenPort = 23;
25*dffd6523SWilliam A. Kennington III 
26*dffd6523SWilliam A. Kennington III stdplus::ManagedFd createListener()
27*dffd6523SWilliam A. Kennington III {
28*dffd6523SWilliam A. Kennington III     using namespace stdplus::fd;
29*dffd6523SWilliam A. Kennington III     auto sock =
30*dffd6523SWilliam A. Kennington III         socket(SocketDomain::INet6, SocketType::Stream, SocketProto::TCP);
31*dffd6523SWilliam A. Kennington III     setFileFlags(sock, getFileFlags(sock).set(stdplus::fd::FileFlag::NonBlock));
32*dffd6523SWilliam A. Kennington III     sockaddr_in6 addr = {};
33*dffd6523SWilliam A. Kennington III     addr.sin6_family = AF_INET6;
34*dffd6523SWilliam A. Kennington III     addr.sin6_port = htons(kListenPort);
35*dffd6523SWilliam A. Kennington III     bind(sock, addr);
36*dffd6523SWilliam A. Kennington III     listen(sock, 10);
37*dffd6523SWilliam A. Kennington III     return sock;
38*dffd6523SWilliam A. Kennington III }
39*dffd6523SWilliam A. Kennington III 
40*dffd6523SWilliam A. Kennington III int main()
41*dffd6523SWilliam A. Kennington III {
42*dffd6523SWilliam A. Kennington III     try
43*dffd6523SWilliam A. Kennington III     {
44*dffd6523SWilliam A. Kennington III         auto listener = createListener();
45*dffd6523SWilliam A. Kennington III         auto event = sdeventplus::Event::get_default();
46*dffd6523SWilliam A. Kennington III         sdeventplus::source::IO do_accept(
47*dffd6523SWilliam A. Kennington III             event, listener.get(), EPOLLIN | EPOLLET,
48*dffd6523SWilliam A. Kennington III             [&](sdeventplus::source::IO&, int, uint32_t) {
49*dffd6523SWilliam A. Kennington III                 while (stdplus::fd::accept(listener))
50*dffd6523SWilliam A. Kennington III                     ;
51*dffd6523SWilliam A. Kennington III             });
52*dffd6523SWilliam A. Kennington III         return event.loop();
53*dffd6523SWilliam A. Kennington III     }
54*dffd6523SWilliam A. Kennington III     catch (const std::exception& e)
55*dffd6523SWilliam A. Kennington III     {
56*dffd6523SWilliam A. Kennington III         fmt::print(stderr, "Failed: {}\n", e.what());
57*dffd6523SWilliam A. Kennington III         return 1;
58*dffd6523SWilliam A. Kennington III     }
59*dffd6523SWilliam A. Kennington III }
60