Add IPv4 Configuration File Access Helper

This commit adds support to access an IPv4 Configuration file similar to the Linux dhpc.client ipfcg file.  This version, tailored for deeply embedded systems supports several options to tailor the file and file access to different environments.  It supports:

- Writable as well as read-only configuration files.
- ASCII human readable files as well as smaller binary files.
- It supports using character driver access to constrained media (such as EEPROM).
- Add examples/ipcfg to exercise IPv4 Configuration File support
This commit is contained in:
Gregory Nutt 2020-09-28 11:51:50 -06:00 committed by David Sidrane
parent 1efc805b4e
commit 5e1ba408b4
9 changed files with 1118 additions and 0 deletions

30
examples/ipcfg/Kconfig Normal file
View File

@ -0,0 +1,30 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_IPCFG
tristate "IPv4 Configuration file example"
default n
select FS_TMPFS
---help---
Enable the IPv4 Configuration file example
if EXAMPLES_IPCFG
config EXAMPLES_IPCFG_PROGNAME
string "IPCFG Program name"
default "ipcfg"
---help---
This is the name of the program that will be used when the NSH ELF
program is installed.
config EXAMPLES_IPCFG_PRIORITY
int "IPCFG task priority"
default 100
config EXAMPLES_IPCFG_STACKSIZE
int "IPCFG stack size"
default DEFAULT_TASK_STACKSIZE
endif

24
examples/ipcfg/Make.defs Normal file
View File

@ -0,0 +1,24 @@
############################################################################
# apps/examples/ipcfg/Make.defs
# Adds selected applications to apps/ build
#
# 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.
#
############################################################################
ifneq ($(CONFIG_EXAMPLES_IPCFG),)
CONFIGURED_APPS += $(APPDIR)/examples/ipcfg
endif

34
examples/ipcfg/Makefile Normal file
View File

@ -0,0 +1,34 @@
############################################################################
# apps/examples/ipcfg/Makefile
#
# 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.
#
############################################################################
include $(APPDIR)/Make.defs
# IPv4 Configuration file example built-in application info
PROGNAME = $(CONFIG_EXAMPLES_IPCFG_PROGNAME)
PRIORITY = $(CONFIG_EXAMPLES_IPCFG_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_IPCFG_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_IPCFG)
# Pv4 Configuration file example
MAINSRC = ipcfg_main.c
include $(APPDIR)/Application.mk

196
examples/ipcfg/ipcfg_main.c Normal file
View File

@ -0,0 +1,196 @@
/****************************************************************************
* examples/ipcfg/ipcfg_main.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 <sys/mount.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "fsutils/ipcfg.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_IPCFG_CHARDEV
# error This example will not work with a character device
#endif
#ifndef CONFIG_IPCFG_WRITABLE
# warning This example will not work with a without write support
#endif
#define DEVICE1 "eth0"
#define DEVICE2 "eth1"
#define BOOTPROTO_MAX BOOTPROTO_FALLBACK
/****************************************************************************
* Private Data
****************************************************************************/
static const char *g_proto_name[] =
{
"none", /* BOOTPROTO_NONE */
"static", /* BOOTPROTO_STATIC */
"dhcp", /* BOOTPROTO_DHCP */
"fallback" /* BOOTPROTO_FALLBACK */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ipcfg_dump_addr
****************************************************************************/
static void ipcfg_dump_addr(FAR const char *variable, in_addr_t address)
{
if (address == 0)
{
printf("%s[UNSPECIFIED]\n", variable);
}
else
{
struct in_addr saddr =
{
address
};
printf("%s%s\n", variable, inet_ntoa(saddr));
}
}
/****************************************************************************
* Name: ipcfg_dump_config
****************************************************************************/
static int ipcfg_dump_config(FAR const char *netdev)
{
struct ipcfg_s ipcfg;
int ret;
ret = ipcfg_read(netdev, &ipcfg);
if (ret < 0)
{
fprintf(stderr, "ERROR: ipcfg_read() failed: %d\n", ret);
return ret;
}
/* Dump the content in human readable form */
printf("%s:\n", netdev);
if (ipcfg.proto > BOOTPROTO_MAX)
{
printf("BOOTPROTO: %d [INVALID]\n", ipcfg.proto);
}
else
{
printf("BOOTPROTO: %s\n", g_proto_name[ipcfg.proto]);
}
ipcfg_dump_addr("IPADDR: ", ipcfg.ipaddr);
ipcfg_dump_addr("NETMASK: ", ipcfg.netmask);
ipcfg_dump_addr("ROUTER: ", ipcfg.router);
ipcfg_dump_addr("DNS: ", ipcfg.dnsaddr);
return OK;
}
/****************************************************************************
* Name: ipcfg_write_config
****************************************************************************/
static int ipcfg_write_config(FAR const char *netdev)
{
struct ipcfg_s ipcfg;
int ret;
ipcfg.proto = BOOTPROTO_DHCP;
ipcfg.ipaddr = HTONL(0x0a000002);
ipcfg.netmask = HTONL(0xffffff00);
ipcfg.router = HTONL(0x0a000001);
ipcfg.router = HTONL(0x0a000003);
ret = ipcfg_write(netdev, &ipcfg);
if (ret < 0)
{
fprintf(stderr, "ERROR: ipcfg_read() ipcfg_write: %d\n", ret);
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ipcfg_main
****************************************************************************/
int main(int argc, FAR char *argv[])
{
int ret;
/* Mount the TMPFS file system at the expected location for the IPv4
* Configuration file directory.
*/
ret = mount(NULL, CONFIG_IPCFG_PATH, "tmpfs", 0, NULL);
if (ret < 0)
{
int errcode = errno;
fprintf(stderr, "ERROR: Failed to open " CONFIG_IPCFG_PATH "\n: %d",
errcode);
return EXIT_FAILURE;
}
/* Dump files. These should all fail. */
printf("\n1. Dump before creating configuration files\n\n");
ipcfg_dump_config(DEVICE1);
ipcfg_dump_config(DEVICE2);
#ifdef CONFIG_IPCFG_WRITABLE
/* Create files */
printf("\n2. Create configuration files\n\n");
ipcfg_write_config(DEVICE1);
ipcfg_write_config(DEVICE2);
/* Dump the files again */
printf("\n3. Dump after creating configuration files\n\n");
ipcfg_dump_config(DEVICE1);
ipcfg_dump_config(DEVICE2);
#endif
umount(CONFIG_IPCFG_PATH);
return EXIT_SUCCESS;
}

71
fsutils/ipcfg/Kconfig Normal file
View File

@ -0,0 +1,71 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config FSUTILS_IPCFG
bool "IPv4 Configuration File Support"
default n
depends on NET_IPv4
---help---
Enables support for an IPv4 configuration file that holds IP
address and/or DHCP configuration information for a
specific network device
There is no dependency on IPv4 networking support so this
configuration may be used in testing without a network.
if FSUTILS_IPCFG
config IPCFG_WRITABLE
bool "Writable IPv4 Configuration"
default y
---help---
Can be used to disable writing to the IPv4 Configuration file. This
would be necessary if, for example, the IPv4 Configuration file were
provided on a read-only file system.
config IPCFG_BINARY
bool "Binary IPv4 Configuration File"
default n
---help---
By default, the IPv4 configuration file is an ASCII human readable
file with <varialble>=<value> pairs. A Binary interface may be used
for more constrained media such as EEPROM.
config IPCFG_PATH
string "IPv4 Configuration File Directory"
default "/etc/sysconfig/network-scripts"
---help---
Specifies the full path to the directory or mountpoint that holds
the IPv4 Configuration files. Each individual configuration file
within this directory will have names like ipcfg-eth0.
If CONFIG_IPCFG_CHARDEV is select, this setting is interpreted
differently. In this case, CONFIG_IPCFG_PATH is the full path
to the character driver.
config IPCFG_CHARDEV
bool "Character Driver"
default n
depends on IPCFG_BINARY
---help---
In some use cases, where there is only a single network device and
only a single network device, a character driver on, perhaps, EEPROM
may be used. In this case there is not file system and the
CONFIG_IPCFG_PATH will refer to that character driver.
NOTE that this configuration is only support with CONFIG_IPCFG_BINARY.
config IPCFG_OFFSET
int "Data offset"
default 0
depends on IPCFG_CHARDEV
---help---
Seek to this offset before reading or writing the IPv4 Configuration.
This is only support for the character driver device. This permits
some formatting of, say, EEPROM, so that multiple, different
configurations can be maintained at differnt offsets into the IPv4
Configuration File.
endif # FSUTILS_IPCFG

23
fsutils/ipcfg/Make.defs Normal file
View File

@ -0,0 +1,23 @@
############################################################################
# apps/fsutils/ipcfg/Make.defs
#
# 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.
#
############################################################################
ifeq ($(CONFIG_FSUTILS_IPCFG),y)
CONFIGURED_APPS += $(APPDIR)/fsutils/ipcfg
endif

29
fsutils/ipcfg/Makefile Normal file
View File

@ -0,0 +1,29 @@
############################################################################
# apps/fsutils/ipcfg/Makefile
#
# 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.
#
############################################################################
include $(APPDIR)/Make.defs
# IPv4 Configuration file access library
ifeq ($(CONFIG_FSUTILS_IPCFG),y)
CSRCS += ipcfg.c
endif
include $(APPDIR)/Application.mk

575
fsutils/ipcfg/ipcfg.c Normal file
View File

@ -0,0 +1,575 @@
/****************************************************************************
* apps/fsutils/ipcfg/ipcfg.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 <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "fsutils/ipcfg.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MAX_LINESIZE 80
#define MAX_BOOTPROTO BOOTPROTO_FALLBACK
/****************************************************************************
* Private Data
****************************************************************************/
#if defined(CONFIG_IPCFG_WRITABLE) && !defined(CONFIG_IPCFG_BINARY)
static const char *g_proto_name[] =
{
"none", /* BOOTPROTO_NONE */
"static", /* BOOTPROTO_STATIC */
"dhcp", /* BOOTPROTO_DHCP */
"fallback" /* BOOTPROTO_FALLBACK */
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ipcfg_allocpath
*
* Description:
* Allocate memory for and construct the full path to the IPv4
* Configuration file.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
*
* Returned Value:
* A pointer to the allocated path is returned. NULL is returned only on
* on a failure to allocate.
*
****************************************************************************/
static inline FAR char *ipcfg_allocpath(FAR const char *netdev)
{
#ifndef CONFIG_IPCFG_CHARDEV
FAR char *path = NULL;
int ret;
/* Create the full path to the ipcfg file for the network device.
* the path of CONFIG_IPCFG_PATH returns to a directory containing
* multiple files of the form ipcfg-<dev> where <dev> is the network
* device name. For example, ipcfg-eth0.
*/
ret = asprintf(&path, CONFIG_IPCFG_PATH "/ipcfg-%s", netdev);
if (ret < 0 || path == NULL)
{
/* Assume that asprintf failed to allocate memory */
fprintf(stderr, "ERROR: Failed to create path to ipcfg file: %d\n",
ret);
return NULL;
}
return path;
#else
/* In this case CONFIG_IPCFG_PATH is the full path to a character device
* that describes the configuration of a single network device.
*
* It is dup'ed to simplify typing (const vs non-const) and to make the
* free operation unconditional.
*/
return strdup(CONFIG_IPCFG_PATH);
#endif
}
/****************************************************************************
* Name: ipcfg_open (for ASCII mode)
*
* Description:
* Form the complete path to the ipcfg file and open it.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* stream - Location to return the opened stream
* mode - File fopen mode
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
#ifndef CONFIG_IPCFG_BINARY
static int ipcfg_open(FAR const char *netdev, FAR FILE **stream,
FAR const char *mode)
{
FAR char *path;
int ret;
/* Create the full path to the ipcfg file for the network device */
path = ipcfg_allocpath(netdev);
if (path == NULL)
{
/* Assume failure to allocate memory */
fprintf(stderr, "ERROR: Failed to create path to ipcfg file\n");
return -ENOMEM;
}
/* Now open the file */
*stream = fopen(path, mode);
ret = OK;
if (*stream == NULL)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
}
free(path);
return ret;
}
#endif
/****************************************************************************
* Name: ipcfg_open (for binary mode)
*
* Description:
* Form the complete path to the ipcfg file and open it.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* 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 *netdev, int oflags, mode_t mode)
{
FAR char *path;
int fd;
int ret;
/* Create the full path to the ipcfg file for the network device */
path = ipcfg_allocpath(netdev);
if (path == NULL)
{
/* Assume failure to allocate memory */
fprintf(stderr, "ERROR: Failed to create path to ipcfg file\n");
return -ENOMEM;
}
/* Now open the file */
fd = open(path, oflags, mode);
ret = OK;
if (fd < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to open %s: %d\n", path, ret);
goto errout_with_path;
}
#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);
}
#endif
errout_with_path:
free(path);
return ret;
}
#endif
/****************************************************************************
* 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_putaddr
*
* 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:
* None.
*
****************************************************************************/
#if defined(CONFIG_IPCFG_WRITABLE) && !defined(CONFIG_IPCFG_BINARY)
static void ipcfg_putaddr(FAR FILE *stream, FAR const char *variable,
in_addr_t address)
{
/* REVISIT: inet_ntoa() is not thread safe. */
if (address != 0)
{
struct in_addr saddr =
{
address
};
fprintf(stream, "%s=%s\n", variable, inet_ntoa(saddr));
}
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ipcfg_read
*
* Description:
* Read and parse the IP configuration file for the specified network
* device.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - Pointer to a user provided location to receive the IP
* configuration.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
{
#ifdef CONFIG_IPCFG_BINARY
ssize_t nread;
int fd;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
/* Open the file */
fd = ipcfg_open(netdev, O_RDONLY, 0666);
if (fd < 0)
{
return fd;
}
/* Read the file content */
nread = read(fd, ipcfg, sizeof(struct ipcfg_s));
if (nread < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to read file: %d\n", ret);
}
else if (nread != sizeof(struct ipcfg_s))
{
ret = -EIO;
fprintf(stderr, "ERROR: Bad read size: %ld\n", (long)nread);
}
else
{
ret = OK;
}
close(fd);
return ret;
#else
FAR FILE *stream;
char line[MAX_LINESIZE];
int index;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
/* Open the file */
ret = ipcfg_open(netdev, &stream, "r");
if (ret < 0)
{
return ret;
}
/* Process each line in the file */
memset(ipcfg, 0, sizeof(FAR struct ipcfg_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, "BOOTPROTO") == 0)
{
if (strcmp(value, "none") == 0)
{
ipcfg->proto = BOOTPROTO_NONE;
}
else if (strcmp(value, "static") == 0)
{
ipcfg->proto = BOOTPROTO_STATIC;
}
else if (strcmp(value, "dhcp") == 0)
{
ipcfg->proto = BOOTPROTO_DHCP;
}
else if (strcmp(value, "fallback") == 0)
{
ipcfg->proto = BOOTPROTO_FALLBACK;
}
else
{
fprintf(stderr, "ERROR: Unrecognized BOOTPROTO: %s=%s\n",
variable, value);
}
}
else if (strcmp(variable, "IPADDR") == 0)
{
ipcfg->ipaddr = inet_addr(value);
}
else if (strcmp(variable, "NETMASK") == 0)
{
ipcfg->netmask = inet_addr(value);
}
else if (strcmp(variable, "ROUTER") == 0)
{
ipcfg->router = inet_addr(value);
}
else if (strcmp(variable, "DNS") == 0)
{
ipcfg->dnsaddr = inet_addr(value);
}
else
{
fprintf(stderr, "ERROR: Unrecognized variable: %s=%s\n",
variable, value);
}
}
}
/* Close the file and return */
fclose(stream);
return OK;
#endif
}
/****************************************************************************
* Name: ipcfg_write
*
* Description:
* Write the IP configuration file for the specified network device.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - The IP configuration to be written.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
#ifdef CONFIG_IPCFG_WRITABLE
int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg)
{
#ifdef CONFIG_IPCFG_BINARY
ssize_t nwritten;
int fd;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
/* Open the file */
fd = ipcfg_open(netdev, O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (fd < 0)
{
return fd;
}
/* Write the file content */
nwritten = write(fd, ipcfg, sizeof(struct ipcfg_s));
if (nwritten < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to write file: %d\n", ret);
}
else if (nwritten != sizeof(struct ipcfg_s))
{
ret = -EIO;
fprintf(stderr, "ERROR: Bad write size: %ld\n", (long)nwritten);
}
else
{
ret = OK;
}
close(fd);
return ret;
#else
FAR FILE *stream;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
/* Open the file */
ret = ipcfg_open(netdev, &stream, "w");
if (ret < 0)
{
return ret;
}
/* Format and write the file */
if ((unsigned)ipcfg->proto == MAX_BOOTPROTO)
{
fprintf(stderr, "ERROR: Unrecognized BOOTPROTO value: %d\n",
ipcfg->proto);
return -EINVAL;
}
fprintf(stream, "DEVICE=%s\n", netdev);
fprintf(stream, "BOOTPROTO=%s\n", g_proto_name[ipcfg->proto]);
ipcfg_putaddr(stream, "IPADDR", ipcfg->ipaddr);
ipcfg_putaddr(stream, "NETMASK", ipcfg->netmask);
ipcfg_putaddr(stream, "ROUTER", ipcfg->router);
ipcfg_putaddr(stream, "DNS", ipcfg->dnsaddr);
/* Close the file and return */
fclose(stream);
return OK;
#endif
}
#endif

136
include/fsutils/ipcfg.h Normal file
View File

@ -0,0 +1,136 @@
/****************************************************************************
* apps/include/fsutils/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_INCLUDE_FSUTILS_IPCFG_H
#define __APPS_INCLUDE_FSUTILS_IPCFG_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <netinet/in.h>
/****************************************************************************
* Public Types
****************************************************************************/
/* Values for the BOOTPROTO setting */
enum ipcfg_bootproto_e
{
BOOTPROTO_NONE = 0, /* No protocol assigned */
BOOTPROTO_STATIC = 1, /* Use static IP */
BOOTPROTO_DHCP = 2, /* Use DHCP */
BOOTPROTO_FALLBACK = 3 /* Use DHCP with fall back static IP */
};
/* The structure contains the parsed content of the ipcfg-<dev> file.
* Summary of file content:
*
* DEVICE=name
* where name is the name of the physical device.
*
* BOOTPROTO=protocol
* where protocol is one of the following:
*
* none - No protocol selected
* static - Use static IP
* dhcp - The DHCP protocol should be used
* fallback - Use DHCP with fall back static IP
*
* All of the following addresses are in network order. The special value
* zero is used to indicate that the address is not available:
*
* IPADDR=address
* where address is the IPv4 address. Used only with static or fallback
* protocols.
*
* NETMASK=address
* where address is the netmask. Used only with static or fallback
* protocols.
*
* ROUTER=address
* where address is the IPv4 default router address. Used only with
* static or fallback protocols.
*
* DNS=address
* where address is a (optional) name server address.
*/
struct ipcfg_s
{
enum ipcfg_bootproto_e proto; /* Configure for static and/or DHCP */
/* The following fields are required for static/fallback configurations */
in_addr_t ipaddr; /* IPv4 address */
in_addr_t netmask; /* Network mask */
in_addr_t router; /* Default router */
/* The following fields are optional for dhcp and fallback configurations */
in_addr_t dnsaddr; /* Name server address */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: ipcfg_read
*
* Description:
* Read and parse the IP configuration file for the specified network
* device.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - Pointer to a user provided location to receive the IP
* configuration.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg);
/****************************************************************************
* Name: ipcfg_write
*
* Description:
* Write the IP configuration file for the specified network device.
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - The IP configuration to be written.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
#ifdef CONFIG_IPCFG_WRITABLE
int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg);
#endif
#endif /* __APPS_INCLUDE_FSUTILS_IPCFG_H */