ncsi: return interface info from Interface::getInfo()

Rather than expecting the ncsi_util callback to print the interface
info, return the interface info, and print that.

This allows for a specific output formatting function in
ncsi_netlink_main.c, rather than printing directly from the libnl
callback. We reformat for a more structured display of the
package/channel layouts.

We use std::optional for the return value here; it would be nice to use
std::expected instead, and get a full error code, but that's not quite
working with clang-18 at present. Even if we have an error code though,
we're just going to return EXIT_FAILURE anyway.

Tested: Invoked on a simlated dual-channel NCSI package:

    # ncsi-netlink -x 2 --info
    <7> Get Info , PACKAGE : 0xffffffffffffffff, INTERFACE: 0x7e8bf9bc
    <7> Package id : 0
    <7>   package is forced
    <7>     Channel id : 0
    <7>       version 1.2 (p0c00)
    <7>       link state 0x40022f
    <7>     Channel id : 1
    <7>       version 1.2 (p0c01)
    <7>       link state 0x40022f

Change-Id: Idb62cc6695da67f4415ed9b0e7950c506018d630
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
diff --git a/src/ncsi_netlink_main.cpp b/src/ncsi_netlink_main.cpp
index 04e0cbc..d5c6fc5 100644
--- a/src/ncsi_netlink_main.cpp
+++ b/src/ncsi_netlink_main.cpp
@@ -28,6 +28,50 @@
     exit(EXIT_FAILURE);
 }
 
+static void printInfo(phosphor::network::ncsi::InterfaceInfo& info)
+{
+    using namespace phosphor::network::ncsi;
+
+    for (PackageInfo& pkg : info.packages)
+    {
+        lg2::debug("Package id : {ID}", "ID", pkg.id);
+        if (pkg.forced)
+        {
+            lg2::debug("  package is forced");
+        }
+        for (ChannelInfo& chan : pkg.channels)
+        {
+            lg2::debug("    Channel id : {ID}", "ID", chan.id);
+            if (chan.forced)
+            {
+                lg2::debug("    channel is forced");
+            }
+            if (chan.active)
+            {
+                lg2::debug("    channel is active");
+            }
+
+            lg2::debug("      version {MAJOR}.{MINOR} ({STR})", "MAJOR",
+                       chan.version_major, "MINOR", chan.version_minor, "STR",
+                       chan.version);
+
+            lg2::debug("      link state {LINK}", "LINK", lg2::hex,
+                       chan.link_state);
+
+            auto& vlans = chan.vlan_ids;
+
+            if (!vlans.empty())
+            {
+                lg2::debug("      Actve VLAN IDs:");
+                for (uint16_t vlan : vlans)
+                {
+                    lg2::debug("        VID: {VLAN_ID}", "VLAN_ID", vlan);
+                }
+            }
+        }
+    }
+}
+
 int main(int argc, char** argv)
 {
     using namespace phosphor::network;
@@ -153,7 +197,12 @@
     }
     else if ((options)["info"] == "true")
     {
-        return interface.getInfo(packageInt);
+        auto info = interface.getInfo(packageInt);
+        if (!info)
+        {
+            return EXIT_FAILURE;
+        }
+        printInfo(*info);
     }
     else if ((options)["clear"] == "true")
     {