You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2020/10/04 05:47:50 UTC

[GitHub] [incubator-nuttx-apps] xiaoxiang781216 commented on a change in pull request #417: apps/fsutils/ipcfg: Add support for IPv6

xiaoxiang781216 commented on a change in pull request #417:
URL: https://github.com/apache/incubator-nuttx-apps/pull/417#discussion_r499205762



##########
File path: fsutils/ipcfg/ipcfg.h
##########
@@ -0,0 +1,237 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_FSUTILS_IPCFG_IPCFG_H
+#define __APPS_FSUTILS_IPCFG_IPCFG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <netinet/in.h>
+
+#include "fsutils/ipcfg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_LINESIZE  80
+#define MAX_IPv4PROTO IPv4PROTO_FALLBACK
+#define MAX_IPv6PROTO IPv6PROTO_FALLBACK
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* IP Configuration record header. */
+
+struct ipcfg_header_s
+{
+  uint8_t next;         /* Offset to the next IP configuration record */
+  sa_family_t type;     /* Must be AF_INET */

Review comment:
       AF_INET, not true anymore?

##########
File path: fsutils/ipcfg/ipcfg_text.c
##########
@@ -0,0 +1,810 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg_text.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <arpa/inet.h>
+
+#include "fsutils/ipcfg.h"
+#include "ipcfg.h"
+
+#ifndef CONFIG_IPCFG_BINARY
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv4)
+static const char *g_ipv4proto_name[] =
+{
+  "none",      /* IPv4PROTO_NONE */
+  "static",    /* IPv4PROTO_STATIC */
+  "dhcp",      /* IPv4PROTO_DHCP */
+  "fallback"   /* IPv4PROTO_FALLBACK */
+};
+#endif
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv6)
+static const char *g_ipv6proto_name[] =
+{
+  "none",      /* IPv6PROTO_NONE */
+  "static",    /* IPv6PROTO_STATIC */
+  "dhcp",      /* IPv6PROTO_AUTOCONF */

Review comment:
       dhcp->autoconf to match the read path

##########
File path: fsutils/ipcfg/ipcfg.h
##########
@@ -0,0 +1,237 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_FSUTILS_IPCFG_IPCFG_H
+#define __APPS_FSUTILS_IPCFG_IPCFG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <netinet/in.h>
+
+#include "fsutils/ipcfg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_LINESIZE  80
+#define MAX_IPv4PROTO IPv4PROTO_FALLBACK
+#define MAX_IPv6PROTO IPv6PROTO_FALLBACK
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* IP Configuration record header. */
+
+struct ipcfg_header_s
+{
+  uint8_t next;         /* Offset to the next IP configuration record */
+  sa_family_t type;     /* Must be AF_INET */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_BINARY) && defined(CONFIG_NET_IPv4)
+int ipcfg_read_binary_ipv4(FAR const char *path,
+                           FAR struct ipv4cfg_s *ipv4cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv6
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to

Review comment:
       ipv4cfg->ipv6cfg, IPv4->IPv6

##########
File path: fsutils/ipcfg/ipcfg.h
##########
@@ -0,0 +1,237 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_FSUTILS_IPCFG_IPCFG_H
+#define __APPS_FSUTILS_IPCFG_IPCFG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <netinet/in.h>
+
+#include "fsutils/ipcfg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_LINESIZE  80
+#define MAX_IPv4PROTO IPv4PROTO_FALLBACK
+#define MAX_IPv6PROTO IPv6PROTO_FALLBACK
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* IP Configuration record header. */
+
+struct ipcfg_header_s
+{
+  uint8_t next;         /* Offset to the next IP configuration record */
+  sa_family_t type;     /* Must be AF_INET */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_BINARY) && defined(CONFIG_NET_IPv4)
+int ipcfg_read_binary_ipv4(FAR const char *path,
+                           FAR struct ipv4cfg_s *ipv4cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv6
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.

Review comment:
       IPv4->IPv6

##########
File path: fsutils/ipcfg/ipcfg_binary.c
##########
@@ -0,0 +1,567 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg_binary.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "fsutils/ipcfg.h"
+#include "ipcfg.h"
+
+#ifdef CONFIG_IPCFG_BINARY
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_open (for binary mode)
+ *
+ * Description:
+ *   Form the complete path to the ipcfg file and open it.
+ *
+ * Input Parameters:
+ *   path   - The full path to the IP configuration file
+ *   oflags - File open flags
+ *   mode   - File creation mode
+ *
+ * Returned Value:
+ *   The open file descriptor is returned on success; a negated errno value
+ *   is returned on any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_IPCFG_BINARY
+static int ipcfg_open(FAR const char *path, int oflags, mode_t mode)
+{
+  int fd;
+  int ret;
+
+  /* Now open the file */
+
+  fd  = open(path, oflags, mode);
+  if (fd < 0)
+    {
+      ret = -errno;
+      if (ret != -ENOENT)
+        {
+          fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
+        }
+
+      return ret;
+    }
+
+#if defined(CONFIG_IPCFG_OFFSET) && CONFIG_IPCFG_OFFSET > 0
+  /* If the binary file is accessed on a character device as a binary
+   * file, then there is also an option to seek to a location on the
+   * media before reading or writing the file.
+   */
+
+  ret = lseek(fd, CONFIG_IPCFG_OFFSET, SEEK_SET);
+  if (ret < 0)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to seek to $ld: %d\n",
+              (long)CONFIG_IPCFG_OFFSET, ret);
+
+      close(fd);
+      return ret;
+    }
+
+#endif
+
+  return fd;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary
+ *
+ * Description:
+ *   Read from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   fd     - File descriptor of the open file to read from
+ *   buffer - Location to read from
+ *   nbytes - Number of bytes to read
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int ipcfg_read_binary(int fd, FAR void *buffer, size_t nbytes)
+{
+  ssize_t nread;
+  int ret;
+
+  /* Read from the file */
+
+  nread = read(fd, buffer, nbytes);
+  if (nread < 0)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to read from file: %d\n", ret);
+    }
+  else if (nread != nbytes)
+    {
+      ret = -EIO;
+      fprintf(stderr, "ERROR: Bad read size: %ld\n", (long)nread);
+    }
+  else
+    {
+      ret = OK;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: ipcfg_write_binary
+ *
+ * Description:
+ *   Write to a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   fd     - File descriptor of the open file to write to
+ *   buffer - Location to write to
+ *   nbytes - Number of bytes to wrtie
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_IPCFG_WRITABLE
+static int ipcfg_write_binary(int fd, FAR const void *buffer, size_t nbytes)
+{
+  ssize_t nwritten;
+  int ret;
+
+  /* Read from the file */
+
+  nwritten = write(fd, buffer, nbytes);
+  if (nwritten < 0)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to write to file: %d\n", ret);
+    }
+  else if (nwritten != nbytes)
+    {
+      ret = -EIO;
+      fprintf(stderr, "ERROR: Bad write size: %ld\n", (long)nwritten);
+    }
+  else
+    {
+      ret = OK;
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_find_binary
+ *
+ * Description:
+ *   Read the location of IPv4 data in a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   fd     - File descriptor of the open file to read from
+ *   af     - Identifies the address family whose IP configuration is
+ *            requested.  May be either AF_INET or AF_INET6.
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int ipcfg_find_binary(int fd, sa_family_t af)
+{
+  struct ipcfg_header_s hdr;
+  off_t pos;
+  int ret;
+
+  for (; ; )
+    {
+      /* Read the header (careful.. could be uninitialized in the case of a
+       * character driver).
+       */
+
+      ret = ipcfg_read_binary(fd, &hdr, sizeof(struct ipcfg_header_s));
+      if (ret < 0)
+        {
+          /* Return on any read error */
+
+          return (int)ret;
+        }
+      else if (hdr.type == af)
+        {
+          return OK;
+        }
+      else if (hdr.type != AF_INET && hdr.type != AF_INET6)
+        {
+          return -EINVAL;
+        }
+      else if (hdr.next == 0)
+        {
+          fprintf(stderr, "ERROR: IP configuration not found\n");
+          return -ENOENT;
+        }
+
+      /* Skip to the next IP configuration record */
+
+      pos = lseek(fd, hdr.next, SEEK_CUR);
+      if (pos < 0)
+        {
+          ret = -errno;
+          fprintf(stderr, "ERROR: lseek failed: %d\n", ret);
+          return ret;
+        }
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+int ipcfg_read_binary_ipv4(FAR const char *path,
+                           FAR struct ipv4cfg_s *ipv4cfg)
+{
+  int fd;
+  int ret;
+
+  DEBUGASSERT(path != NULL && ipv4cfg != NULL);
+
+  /* Open the file for reading */
+
+  fd = ipcfg_open(path, O_RDONLY, 0666);
+  if (fd < 0)
+    {
+      return fd;
+    }
+
+  /* Find the IPv4 binary in the IP configuration file */
+
+  ret = ipcfg_find_binary(fd, AF_INET);
+  if (ret < 0)
+    {
+      goto errout_with_fd;
+    }
+
+  /* Read the IPv4 Configuration */
+
+  ret = ipcfg_read_binary(fd, ipv4cfg, sizeof(struct ipv4cfg_s));
+
+errout_with_fd:
+  close(fd);
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv6
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.

Review comment:
       IPv4->IPv6

##########
File path: fsutils/ipcfg/ipcfg_binary.c
##########
@@ -0,0 +1,567 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg_binary.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "fsutils/ipcfg.h"
+#include "ipcfg.h"
+
+#ifdef CONFIG_IPCFG_BINARY
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_open (for binary mode)
+ *
+ * Description:
+ *   Form the complete path to the ipcfg file and open it.
+ *
+ * Input Parameters:
+ *   path   - The full path to the IP configuration file
+ *   oflags - File open flags
+ *   mode   - File creation mode
+ *
+ * Returned Value:
+ *   The open file descriptor is returned on success; a negated errno value
+ *   is returned on any failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_IPCFG_BINARY
+static int ipcfg_open(FAR const char *path, int oflags, mode_t mode)
+{
+  int fd;
+  int ret;
+
+  /* Now open the file */
+
+  fd  = open(path, oflags, mode);
+  if (fd < 0)
+    {
+      ret = -errno;
+      if (ret != -ENOENT)
+        {
+          fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
+        }
+
+      return ret;
+    }
+
+#if defined(CONFIG_IPCFG_OFFSET) && CONFIG_IPCFG_OFFSET > 0
+  /* If the binary file is accessed on a character device as a binary
+   * file, then there is also an option to seek to a location on the
+   * media before reading or writing the file.
+   */
+
+  ret = lseek(fd, CONFIG_IPCFG_OFFSET, SEEK_SET);
+  if (ret < 0)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to seek to $ld: %d\n",
+              (long)CONFIG_IPCFG_OFFSET, ret);
+
+      close(fd);
+      return ret;
+    }
+
+#endif
+
+  return fd;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary
+ *
+ * Description:
+ *   Read from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   fd     - File descriptor of the open file to read from
+ *   buffer - Location to read from
+ *   nbytes - Number of bytes to read
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int ipcfg_read_binary(int fd, FAR void *buffer, size_t nbytes)
+{
+  ssize_t nread;
+  int ret;
+
+  /* Read from the file */
+
+  nread = read(fd, buffer, nbytes);
+  if (nread < 0)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to read from file: %d\n", ret);
+    }
+  else if (nread != nbytes)
+    {
+      ret = -EIO;
+      fprintf(stderr, "ERROR: Bad read size: %ld\n", (long)nread);
+    }
+  else
+    {
+      ret = OK;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: ipcfg_write_binary
+ *
+ * Description:
+ *   Write to a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   fd     - File descriptor of the open file to write to
+ *   buffer - Location to write to
+ *   nbytes - Number of bytes to wrtie
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_IPCFG_WRITABLE
+static int ipcfg_write_binary(int fd, FAR const void *buffer, size_t nbytes)
+{
+  ssize_t nwritten;
+  int ret;
+
+  /* Read from the file */
+
+  nwritten = write(fd, buffer, nbytes);
+  if (nwritten < 0)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to write to file: %d\n", ret);
+    }
+  else if (nwritten != nbytes)
+    {
+      ret = -EIO;
+      fprintf(stderr, "ERROR: Bad write size: %ld\n", (long)nwritten);
+    }
+  else
+    {
+      ret = OK;
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_find_binary
+ *
+ * Description:
+ *   Read the location of IPv4 data in a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   fd     - File descriptor of the open file to read from
+ *   af     - Identifies the address family whose IP configuration is
+ *            requested.  May be either AF_INET or AF_INET6.
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int ipcfg_find_binary(int fd, sa_family_t af)
+{
+  struct ipcfg_header_s hdr;
+  off_t pos;
+  int ret;
+
+  for (; ; )
+    {
+      /* Read the header (careful.. could be uninitialized in the case of a
+       * character driver).
+       */
+
+      ret = ipcfg_read_binary(fd, &hdr, sizeof(struct ipcfg_header_s));
+      if (ret < 0)
+        {
+          /* Return on any read error */
+
+          return (int)ret;
+        }
+      else if (hdr.type == af)
+        {
+          return OK;
+        }
+      else if (hdr.type != AF_INET && hdr.type != AF_INET6)
+        {
+          return -EINVAL;
+        }
+      else if (hdr.next == 0)
+        {
+          fprintf(stderr, "ERROR: IP configuration not found\n");
+          return -ENOENT;
+        }
+
+      /* Skip to the next IP configuration record */
+
+      pos = lseek(fd, hdr.next, SEEK_CUR);
+      if (pos < 0)
+        {
+          ret = -errno;
+          fprintf(stderr, "ERROR: lseek failed: %d\n", ret);
+          return ret;
+        }
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+int ipcfg_read_binary_ipv4(FAR const char *path,
+                           FAR struct ipv4cfg_s *ipv4cfg)
+{
+  int fd;
+  int ret;
+
+  DEBUGASSERT(path != NULL && ipv4cfg != NULL);
+
+  /* Open the file for reading */
+
+  fd = ipcfg_open(path, O_RDONLY, 0666);
+  if (fd < 0)
+    {
+      return fd;
+    }
+
+  /* Find the IPv4 binary in the IP configuration file */
+
+  ret = ipcfg_find_binary(fd, AF_INET);
+  if (ret < 0)
+    {
+      goto errout_with_fd;
+    }
+
+  /* Read the IPv4 Configuration */
+
+  ret = ipcfg_read_binary(fd, ipv4cfg, sizeof(struct ipv4cfg_s));
+
+errout_with_fd:
+  close(fd);
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv6
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to

Review comment:
       ipv6cfg - Location to read IPv6 configration to

##########
File path: fsutils/ipcfg/ipcfg_text.c
##########
@@ -0,0 +1,810 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg_text.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <arpa/inet.h>
+
+#include "fsutils/ipcfg.h"
+#include "ipcfg.h"
+
+#ifndef CONFIG_IPCFG_BINARY
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv4)
+static const char *g_ipv4proto_name[] =
+{
+  "none",      /* IPv4PROTO_NONE */
+  "static",    /* IPv4PROTO_STATIC */
+  "dhcp",      /* IPv4PROTO_DHCP */
+  "fallback"   /* IPv4PROTO_FALLBACK */
+};
+#endif
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv6)
+static const char *g_ipv6proto_name[] =
+{
+  "none",      /* IPv6PROTO_NONE */
+  "static",    /* IPv6PROTO_STATIC */
+  "dhcp",      /* IPv6PROTO_AUTOCONF */
+  "fallback"   /* IPv4PROTO_FALLBACK */
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_trim
+ *
+ * Description:
+ *   Skip over any whitespace.
+ *
+ * Input Parameters:
+ *   line  - Pointer to line buffer
+ *   index - Current index into the line buffer
+ *
+ * Returned Value:
+ *   New value of index.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_IPCFG_BINARY
+static int ipcfg_trim(FAR char *line, int index)
+{
+  int ret;
+  while (line[index] != '\0' && isspace(line[index]))
+    {
+      index++;
+    }
+
+  ret = index;
+  while (line[index] != '\0')
+    {
+      if (!isprint(line[index]))
+        {
+          line[index] = '\0';
+          break;
+        }
+
+      index++;
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_put_ipv4addr
+ *
+ * Description:
+ *   Write a <variable>=<address> value pair to the stream.
+ *
+ * Input Parameters:
+ *   stream   - The output stream
+ *   variable - The variable namespace
+ *   address  - The IP address to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv4)
+static int ipcfg_put_ipv4addr(FAR FILE *stream, FAR const char *variable,
+                              in_addr_t address)
+{
+  if (address != 0)
+    {
+      struct in_addr saddr =
+      {
+        address
+      };
+
+      char converted[INET_ADDRSTRLEN];
+
+      /* Convert the address to ASCII text */
+
+      if (inet_ntop(AF_INET, &saddr, converted, INET_ADDRSTRLEN) == NULL)
+        {
+          int ret = -errno;
+          fprintf(stderr, "ERROR: inet_ntop() failed: %d\n", ret);
+          return ret;
+        }
+
+      fprintf(stream, "%s=%s\n", variable, converted);
+    }
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_check_ipv6addr
+ *
+ * Description:
+ *   Check for a valid IPv6 address, i.e., not all zeroes.
+ *
+ * Input Parameters:
+ *   address - A pointer to the address to check.
+ *
+ * Returned value:
+ *   Zero (OK) is returned if the address is non-zero.  -ENXIO is returned if
+ *   the address is zero.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+static int ipcfg_check_ipv6addr(FAR const struct in6_addr *address)
+{
+  int i;
+
+  for (i = 0; i < 4; i++)
+    {
+      if (address->s6_addr32[i] != 0)
+        {
+          return OK;
+        }
+    }
+
+  return -ENXIO;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_put_ipv6addr
+ *
+ * Description:
+ *   Write a <variable>=<address> value pair to the stream.
+ *
+ * Input Parameters:
+ *   stream   - The output stream
+ *   variable - The variable namespace
+ *   address  - The IP address to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv6)
+static int ipcfg_put_ipv6addr(FAR FILE *stream, FAR const char *variable,
+                              FAR const struct in6_addr *address)
+{
+  /* If the address is all zero, then omit it */
+
+  if (ipcfg_check_ipv6addr(address) == OK)
+    {
+      char converted[INET6_ADDRSTRLEN];
+
+      /* Convert the address to ASCII text */
+
+      if (inet_ntop(AF_INET6, address, converted, INET6_ADDRSTRLEN) == NULL)
+        {
+          int ret = -errno;
+          fprintf(stderr, "ERROR: inet_ntop() failed: %d\n", ret);
+          return ret;
+        }
+
+      fprintf(stream, "%s=%s\n", variable, converted);
+    }
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_ipv4
+ *
+ * Description:
+ *   Write the IPv4 configuration to a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   stream  - Stream of the open file to write to
+ *   ipv4cfg - The IPv4 configration to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv4)
+static int ipcfg_write_ipv4(FAR FILE *stream,
+                            FAR const struct ipv4cfg_s *ipv4cfg)
+{
+  /* Format and write the file */
+
+  if ((unsigned)ipv4cfg->proto > MAX_IPv4PROTO)
+    {
+      fprintf(stderr, "ERROR: Unrecognized IPv4PROTO value: %d\n",
+              ipv4cfg->proto);
+      return -EINVAL;
+    }
+
+  fprintf(stream, "IPv4PROTO=%s\n", g_ipv4proto_name[ipv4cfg->proto]);
+
+  ipcfg_put_ipv4addr(stream, "IPv4IPADDR",  ipv4cfg->ipaddr);
+  ipcfg_put_ipv4addr(stream, "IPv4NETMASK", ipv4cfg->netmask);
+  ipcfg_put_ipv4addr(stream, "IPv4ROUTER",  ipv4cfg->router);
+  ipcfg_put_ipv4addr(stream, "IPv4DNS",     ipv4cfg->dnsaddr);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_ipv6
+ *
+ * Description:
+ *   Write the IPv6 configuration to a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   stream  - Stream of the open file to write to
+ *   ipv6cfg - The IPv6 configration to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv6)
+static int ipcfg_write_ipv6(FAR FILE *stream,
+                            FAR const struct ipv6cfg_s *ipv6cfg)
+{
+  /* Format and write the file */
+
+  if ((unsigned)ipv6cfg->proto > MAX_IPv6PROTO)
+    {
+      fprintf(stderr, "ERROR: Unrecognized IPv6PROTO value: %d\n",
+              ipv6cfg->proto);
+      return -EINVAL;
+    }
+
+  fprintf(stream, "IPv6PROTO=%s\n", g_ipv6proto_name[ipv6cfg->proto]);
+
+  ipcfg_put_ipv6addr(stream, "IPv6IPADDR",  &ipv6cfg->ipaddr);
+  ipcfg_put_ipv6addr(stream, "IPv6NETMASK", &ipv6cfg->netmask);
+  ipcfg_put_ipv6addr(stream, "IPv6ROUTER",  &ipv6cfg->router);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_read_text_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   netdev  - Network device name string
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+int ipcfg_read_text_ipv4(FAR const char *path, FAR const char *netdev,
+                         FAR struct ipv4cfg_s *ipv4cfg)
+{
+  char line[MAX_LINESIZE];
+  FAR FILE *stream;
+  int index;
+  int ret = -ENOENT;
+
+  DEBUGASSERT(stream != NULL && ipv4cfg != NULL);
+
+  /* Open the file for reading */
+
+  stream = fopen(path, "r");
+  if (stream == NULL)
+    {
+      ret = -errno;
+      if (ret != -ENOENT)
+        {
+          fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
+        }
+
+      return ret;
+    }
+
+  /* Process each line in the file */
+
+  memset(ipv4cfg, 0, sizeof(FAR struct ipv4cfg_s));
+
+  while (fgets(line, MAX_LINESIZE, stream) != NULL)
+    {
+      /* Skip any leading whitespace */
+
+      index = ipcfg_trim(line, 0);
+
+      /* Check for a blank line or a comment */
+
+      if (line[index] != '\0' && line[index] != '#')
+        {
+          FAR char *variable = &line[index];
+          FAR char *value;
+
+          /* Expect <variable>=<value> pair */
+
+          value = strchr(variable, '=');
+          if (value == NULL)
+            {
+              fprintf(stderr, "ERROR: Skipping malformed line in file: %s\n",
+                      line);
+              continue;
+            }
+
+          /* NUL-terminate the variable string */
+
+          *value++ = '\0';
+
+          /* Process the variable assignment */
+
+          if (strcmp(variable, "DEVICE") == 0)
+            {
+              /* Just assure that it matches the filename */
+
+              if (strcmp(value, netdev) != 0)
+                {
+                  fprintf(stderr, "ERROR: Bad device in file: %s=%s\n",
+                          variable, value);
+                }
+            }
+          else if (strcmp(variable, "IPv4PROTO") == 0)
+            {
+              if (strcmp(value, "none") == 0)
+                {
+                  ipv4cfg->proto = IPv4PROTO_NONE;
+                }
+              else if (strcmp(value, "static") == 0)
+                {
+                  ipv4cfg->proto = IPv4PROTO_STATIC;
+                }
+              else if (strcmp(value, "dhcp") == 0)
+                {
+                  ipv4cfg->proto = IPv4PROTO_DHCP;
+                }
+              else if (strcmp(value, "fallback") == 0)
+                {
+                  ipv4cfg->proto = IPv4PROTO_FALLBACK;
+                }
+              else
+                {
+                  fprintf(stderr, "ERROR: Unrecognized IPv4PROTO: %s=%s\n",
+                          variable, value);
+                }
+
+              /* Assume IPv4 settings are present if the IPv4BOOTPROTO
+               * setting is encountered.
+               */
+
+              ret = OK;
+            }
+          else if (strcmp(variable, "IPv4IPADDR") == 0)
+            {
+              ipv4cfg->ipaddr = inet_addr(value);
+            }
+          else if (strcmp(variable, "IPv4NETMASK") == 0)
+            {
+              ipv4cfg->netmask = inet_addr(value);
+            }
+          else if (strcmp(variable, "IPv4ROUTER") == 0)
+            {
+              ipv4cfg->router = inet_addr(value);
+            }
+          else if (strcmp(variable, "IPv4DNS") == 0)
+            {
+              ipv4cfg->dnsaddr = inet_addr(value);
+            }
+
+          /* Anything other than some IPv6 settings would be an error.
+           * This is a sloppy check because it does not detect invalid
+           * names variables that begin with "IPv6".
+           */
+
+          else if (strncmp(variable, "IPv6", 4) != 0)
+            {
+              fprintf(stderr, "ERROR: Unrecognized variable: %s=%s\n",
+                     variable, value);
+            }
+        }
+    }
+
+  /* Close the file and return */
+
+  fclose(stream);
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_text_ipv6
+ *
+ * Description:
+ *   Read IPv6 configuration from a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   netdev  - Network device name string
+ *   ipv6cfg - Location to read IPv6 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+int ipcfg_read_text_ipv6(FAR const char *path, FAR const char *netdev,
+                         FAR struct ipv6cfg_s *ipv6cfg)
+{
+  char line[MAX_LINESIZE];
+  FAR FILE *stream;
+  bool found = false;
+  int index;
+  int ret;
+
+  DEBUGASSERT(path != NULL && netdev != NULL && ipv6cfg != NULL);
+
+  /* Open the file for reading */
+
+  stream = fopen(path, "r");
+  if (stream == NULL)
+    {
+      ret = -errno;
+      if (ret != -ENOENT)
+        {
+          fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
+        }
+
+      return ret;
+    }
+
+  /* Process each line in the file */
+
+  memset(ipv6cfg, 0, sizeof(FAR struct ipv6cfg_s));
+
+  while (fgets(line, MAX_LINESIZE, stream) != NULL)
+    {
+      /* Skip any leading whitespace */
+
+      index = ipcfg_trim(line, 0);
+
+      /* Check for a blank line or a comment */
+
+      if (line[index] != '\0' && line[index] != '#')
+        {
+          FAR char *variable = &line[index];
+          FAR char *value;
+
+          /* Expect <variable>=<value> pair */
+
+          value = strchr(variable, '=');
+          if (value == NULL)
+            {
+              fprintf(stderr, "ERROR: Skipping malformed line in file: %s\n",
+                      line);
+              continue;
+            }
+
+          /* NUL-terminate the variable string */
+
+          *value++ = '\0';
+
+          /* Process the variable assignment */
+
+          if (strcmp(variable, "DEVICE") == 0)
+            {
+              /* Just assure that it matches the filename */
+
+              if (strcmp(value, netdev) != 0)
+                {
+                  fprintf(stderr, "ERROR: Bad device in file: %s=%s\n",
+                          variable, value);
+                }
+            }
+          else if (strcmp(variable, "IPv6PROTO") == 0)
+            {
+              if (strcmp(value, "none") == 0)
+                {
+                  ipv6cfg->proto = IPv6PROTO_NONE;
+                }
+              else if (strcmp(value, "static") == 0)
+                {
+                  ipv6cfg->proto = IPv6PROTO_STATIC;
+                }
+              else if (strcmp(value, "autoconf") == 0)
+                {
+                  ipv6cfg->proto = IPv6PROTO_AUTOCONF;
+                }
+              else if (strcmp(value, "fallback") == 0)
+                {
+                  ipv6cfg->proto = IPv6PROTO_FALLBACK;
+                }
+              else
+                {
+                  fprintf(stderr, "ERROR: Unrecognized IPv6PROTO: %s=%s\n",
+                          variable, value);
+                }
+
+              /* Assume IPv4 settings are present if the IPv6BOOTPROTO
+               * setting is encountered.
+               */
+
+              found = true;
+            }
+          else if (strcmp(variable, "IPv6IPADDR") == 0)
+            {
+              ret = inet_pton(AF_INET6, value, &ipv6cfg->ipaddr);
+              if (ret < 0)
+                {
+                  ret = -errno;
+                  fprintf(stderr, "ERROR: inet_pton() failed: %d\n", ret);
+                  return ret;
+                }
+            }
+          else if (strcmp(variable, "IPv6NETMASK") == 0)
+            {
+              ret = inet_pton(AF_INET6, value, &ipv6cfg->netmask);
+              if (ret < 0)
+                {
+                  ret = -errno;
+                  fprintf(stderr, "ERROR: inet_pton() failed: %d\n", ret);
+                  return ret;
+                }
+            }
+          else if (strcmp(variable, "IPv6ROUTER") == 0)
+            {
+              ret = inet_pton(AF_INET6, value, &ipv6cfg->router);
+              if (ret < 0)
+                {
+                  ret = -errno;
+                  fprintf(stderr, "ERROR: inet_pton() failed: %d\n", ret);
+                  return ret;
+                }
+            }
+
+          /* Anything other than some IPv4 settings would be an error.
+           * This is a sloppy check because it does not detect invalid
+           * names variables that begin with "IPv4".
+           */
+
+          else if (strncmp(variable, "IPv4", 4) != 0)
+            {
+              fprintf(stderr, "ERROR: Unrecognized variable: %s=%s\n",
+                     variable, value);
+            }
+        }
+    }
+
+  /* Close the file and return */
+
+  fclose(stream);
+  return found ? OK : -ENOENT;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_text_ipv4
+ *
+ * Description:
+ *   Write the IPv4 configuration to a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   netdev  - Network device name string
+ *   ipv4cfg - The IPv4 configration to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv4)
+int ipcfg_write_text_ipv4(FAR const char *path, FAR const char *netdev,
+                          FAR const struct ipv4cfg_s *ipv4cfg)
+{
+#ifdef CONFIG_NET_IPv6
+  struct ipv6cfg_s ipv6cfg;
+  bool ipv6 = false;
+#endif
+  FAR FILE *stream;
+  int ret;
+
+  DEBUGASSERT(stream != NULL && ipv4cfg != NULL);
+
+#ifdef CONFIG_NET_IPv6
+  /* Read any IPv6 data in the file */
+
+  ret = ipcfg_read_text_ipv6(path, netdev, &ipv6cfg);
+  if (ret < 0)
+    {
+      /* -ENOENT is not an error.  It simply means that there is no IPv6
+       * configuration in the file.
+       */
+
+      if (ret != -ENOENT)
+        {
+          return ret;
+        }
+    }
+  else
+    {
+      ipv6 = true;
+    }
+#endif
+
+  /* Open the file for writing (truncates) */
+
+  stream = fopen(path, "w");
+  if (stream == NULL)
+    {
+      ret = -errno;
+      fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
+      return ret;
+    }
+
+  /* Save the device name */
+
+  fprintf(stream, "DEVICE=%s\n", netdev);
+
+  /* Write the IPv4 configuration */
+
+  ret = ipcfg_write_ipv4(stream, ipv4cfg);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+#ifdef CONFIG_NET_IPv6
+  /* Followed by any IPv6 data in the file */
+
+  if (ipv6)
+    {
+      ret = ipcfg_write_ipv6(stream, &ipv6cfg);
+    }
+#endif
+
+  fclose(stream);
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_text_ipv6
+ *
+ * Description:
+ *   Write the IPv6 configuration to a binary IP Configuration file.

Review comment:
       binary->text

##########
File path: fsutils/ipcfg/ipcfg.h
##########
@@ -0,0 +1,237 @@
+/****************************************************************************
+ * apps/fsutils/ipcfg/ipcfg.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_FSUTILS_IPCFG_IPCFG_H
+#define __APPS_FSUTILS_IPCFG_IPCFG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <netinet/in.h>
+
+#include "fsutils/ipcfg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_LINESIZE  80
+#define MAX_IPv4PROTO IPv4PROTO_FALLBACK
+#define MAX_IPv6PROTO IPv6PROTO_FALLBACK
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* IP Configuration record header. */
+
+struct ipcfg_header_s
+{
+  uint8_t next;         /* Offset to the next IP configuration record */
+  sa_family_t type;     /* Must be AF_INET */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_BINARY) && defined(CONFIG_NET_IPv4)
+int ipcfg_read_binary_ipv4(FAR const char *path,
+                           FAR struct ipv4cfg_s *ipv4cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_binary_ipv6
+ *
+ * Description:
+ *   Read IPv4 configuration from a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_BINARY) && defined(CONFIG_NET_IPv6)
+int ipcfg_read_binary_ipv6(FAR const char *path,
+                           FAR struct ipv6cfg_s *ipv6cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_binary_ipv4
+ *
+ * Description:
+ *   Write the IPv4 configuration to a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv4cfg - The IPv4 configration to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_IPCFG_BINARY) && \
+    defined(CONFIG_NET_IPv4)
+int ipcfg_write_binary_ipv4(FAR const char *path,
+                            FAR const struct ipv4cfg_s *ipv4cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_binary_ipv6
+ *
+ * Description:
+ *   Write the IPv6 configuration to a binary IP Configuration file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   ipv6cfg - The IPv6 configration to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_IPCFG_BINARY) && \
+    defined(CONFIG_NET_IPv6)
+int ipcfg_write_binary_ipv6(FAR const char *path,
+                            FAR const struct ipv6cfg_s *ipv6cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_text_ipv4
+ *
+ * Description:
+ *   Read IPv4 configuration from a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   netdev  - Network device name string
+ *   ipv4cfg - Location to read IPv4 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv4
+int ipcfg_read_text_ipv4(FAR const char *path, FAR const char *netdev,
+                         FAR struct ipv4cfg_s *ipv4cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_read_text_ipv6
+ *
+ * Description:
+ *   Read IPv6 configuration from a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   netdev  - Network device name string
+ *   ipv6cfg - Location to read IPv6 configration to
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+int ipcfg_read_text_ipv6(FAR const char *path, FAR const char *netdev,
+                         FAR struct ipv6cfg_s *ipv6cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_text_ipv4
+ *
+ * Description:
+ *   Write the IPv4 configuration to a human-readable, text IP Configuration
+ *   file.
+ *
+ * Input Parameters:
+ *   path    - The full path to the IP configuration file
+ *   netdev  - Network device name string
+ *   ipv4cfg - The IPv4 configration to write
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_IPCFG_WRITABLE) && defined(CONFIG_NET_IPv4)
+int ipcfg_write_text_ipv4(FAR const char *path, FAR const char *netdev,
+                          FAR const struct ipv4cfg_s *ipv4cfg);
+#endif
+
+/****************************************************************************
+ * Name: ipcfg_write_text_ipv6
+ *
+ * Description:
+ *   Write the IPv6 configuration to a binary IP Configuration file.

Review comment:
       binary->text




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org