Merge branch 'iana' into 'master'

ncsi: Add basic Get Version ID response

See merge request slirp/libslirp!122
diff --git a/src/libslirp.h b/src/libslirp.h
index 77396f0..35ddab6 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -90,7 +90,7 @@
 } SlirpCb;
 
 #define SLIRP_CONFIG_VERSION_MIN 1
-#define SLIRP_CONFIG_VERSION_MAX 4
+#define SLIRP_CONFIG_VERSION_MAX 5
 
 typedef struct SlirpConfig {
     /* Version must be provided */
@@ -140,6 +140,10 @@
      * Fields introduced in SlirpConfig version 4 begin
      */
     bool disable_dhcp; /* slirp will not reply to any DHCP requests */
+    /*
+     * Fields introduced in SlirpConfig version 5 begin
+     */
+    uint32_t mfr_id; /* Manufacturer ID (IANA Private Enterprise number) */
 } SlirpConfig;
 
 /* Create a new instance of a slirp stack */
diff --git a/src/ncsi.c b/src/ncsi.c
index f3427bd..5bf731b 100644
--- a/src/ncsi.c
+++ b/src/ncsi.c
@@ -55,8 +55,19 @@
     return checksum;
 }
 
+/* Get Version ID */
+static int ncsi_rsp_handler_gvi(Slirp *slirp, struct ncsi_rsp_pkt_hdr *rnh)
+{
+    struct ncsi_rsp_gvi_pkt *rsp = (struct ncsi_rsp_gvi_pkt *)rnh;
+
+    rsp->ncsi_version = htonl(0xF1F0F000);
+    rsp->mf_id = htonl(slirp->mfr_id);
+
+    return 0;
+}
+
 /* Get Capabilities */
-static int ncsi_rsp_handler_gc(struct ncsi_rsp_pkt_hdr *rnh)
+static int ncsi_rsp_handler_gc(Slirp *slirp, struct ncsi_rsp_pkt_hdr *rnh)
 {
     struct ncsi_rsp_gc_pkt *rsp = (struct ncsi_rsp_gc_pkt *)rnh;
 
@@ -71,7 +82,7 @@
 }
 
 /* Get Link status */
-static int ncsi_rsp_handler_gls(struct ncsi_rsp_pkt_hdr *rnh)
+static int ncsi_rsp_handler_gls(Slirp *slirp, struct ncsi_rsp_pkt_hdr *rnh)
 {
     struct ncsi_rsp_gls_pkt *rsp = (struct ncsi_rsp_gls_pkt *)rnh;
 
@@ -80,7 +91,7 @@
 }
 
 /* Get Parameters */
-static int ncsi_rsp_handler_gp(struct ncsi_rsp_pkt_hdr *rnh)
+static int ncsi_rsp_handler_gp(Slirp *slirp, struct ncsi_rsp_pkt_hdr *rnh)
 {
     struct ncsi_rsp_gp_pkt *rsp = (struct ncsi_rsp_gp_pkt *)rnh;
 
@@ -96,7 +107,7 @@
 static const struct ncsi_rsp_handler {
     unsigned char type;
     int payload;
-    int (*handler)(struct ncsi_rsp_pkt_hdr *rnh);
+    int (*handler)(Slirp *slirp, struct ncsi_rsp_pkt_hdr *rnh);
 } ncsi_rsp_handlers[] = { { NCSI_PKT_RSP_CIS, 4, NULL },
                           { NCSI_PKT_RSP_SP, 4, NULL },
                           { NCSI_PKT_RSP_DP, 4, NULL },
@@ -117,7 +128,7 @@
                           { NCSI_PKT_RSP_EGMF, 4, NULL },
                           { NCSI_PKT_RSP_DGMF, 4, NULL },
                           { NCSI_PKT_RSP_SNFC, 4, NULL },
-                          { NCSI_PKT_RSP_GVI, 40, NULL },
+                          { NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi },
                           { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
                           { NCSI_PKT_RSP_GP, 40, ncsi_rsp_handler_gp },
                           { NCSI_PKT_RSP_GCPS, 172, NULL },
@@ -178,7 +189,7 @@
 
         if (handler->handler) {
             /* TODO: handle errors */
-            handler->handler(rnh);
+            handler->handler(slirp, rnh);
         }
         ncsi_rsp_len += handler->payload;
     } else {
diff --git a/src/slirp.c b/src/slirp.c
index 04bce41..588cada 100644
--- a/src/slirp.c
+++ b/src/slirp.c
@@ -648,6 +648,12 @@
         slirp->cb->init_completed(slirp, slirp->opaque);
     }
 
+    if (cfg->version >= 5) {
+        slirp->mfr_id = cfg->mfr_id;
+    } else {
+        slirp->mfr_id = 0;
+    }
+
     ip6_post_init(slirp);
     return slirp;
 }
diff --git a/src/slirp.h b/src/slirp.h
index 35c2be3..a61ea15 100644
--- a/src/slirp.h
+++ b/src/slirp.h
@@ -151,6 +151,8 @@
 
     bool disable_host_loopback;
 
+    uint32_t mfr_id;
+
     /* mbuf states */
     struct slirp_quehead m_freelist;
     struct slirp_quehead m_usedlist;