diff --git a/examples/ipcfg/Kconfig b/examples/ipcfg/Kconfig new file mode 100644 index 000000000..3fbbfdd86 --- /dev/null +++ b/examples/ipcfg/Kconfig @@ -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 diff --git a/examples/ipcfg/Make.defs b/examples/ipcfg/Make.defs new file mode 100644 index 000000000..970271c67 --- /dev/null +++ b/examples/ipcfg/Make.defs @@ -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 diff --git a/examples/ipcfg/Makefile b/examples/ipcfg/Makefile new file mode 100644 index 000000000..82c6b018c --- /dev/null +++ b/examples/ipcfg/Makefile @@ -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 diff --git a/examples/ipcfg/ipcfg_main.c b/examples/ipcfg/ipcfg_main.c new file mode 100644 index 000000000..6107a50e1 --- /dev/null +++ b/examples/ipcfg/ipcfg_main.c @@ -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 + +#include +#include +#include + +#include + +#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; +} diff --git a/fsutils/ipcfg/Kconfig b/fsutils/ipcfg/Kconfig new file mode 100644 index 000000000..9979f6a3e --- /dev/null +++ b/fsutils/ipcfg/Kconfig @@ -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 = 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 diff --git a/fsutils/ipcfg/Make.defs b/fsutils/ipcfg/Make.defs new file mode 100644 index 000000000..5e44ae68c --- /dev/null +++ b/fsutils/ipcfg/Make.defs @@ -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 diff --git a/fsutils/ipcfg/Makefile b/fsutils/ipcfg/Makefile new file mode 100644 index 000000000..de6dcb259 --- /dev/null +++ b/fsutils/ipcfg/Makefile @@ -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 diff --git a/fsutils/ipcfg/ipcfg.c b/fsutils/ipcfg/ipcfg.c new file mode 100644 index 000000000..43a184222 --- /dev/null +++ b/fsutils/ipcfg/ipcfg.c @@ -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 + +#include +#include +#include +#include +#include + +#include +#include + +#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- where 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 =
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 = 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 diff --git a/include/fsutils/ipcfg.h b/include/fsutils/ipcfg.h new file mode 100644 index 000000000..e594871cc --- /dev/null +++ b/include/fsutils/ipcfg.h @@ -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 + +/**************************************************************************** + * 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- 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 */