ipcfg: Add hooks for future IPv6 support.

This commit adds structures, modifies function prototypes, and renames data to support the future addition of IPv6 support.  This commit does NOT add that IPv6, only the hooks for backward compatible future support.
This commit is contained in:
Gregory Nutt 2020-10-02 10:10:29 -06:00 committed by David Sidrane
parent 536660d062
commit 707e827ded
3 changed files with 217 additions and 85 deletions

View File

@ -46,18 +46,18 @@
#define DEVICE1 "eth0"
#define DEVICE2 "eth1"
#define BOOTPROTO_MAX BOOTPROTO_FALLBACK
#define IPv4PROTO_MAX IPv4PROTO_FALLBACK
/****************************************************************************
* Private Data
****************************************************************************/
static const char *g_proto_name[] =
static const char *g_ipv4proto_name[] =
{
"none", /* BOOTPROTO_NONE */
"static", /* BOOTPROTO_STATIC */
"dhcp", /* BOOTPROTO_DHCP */
"fallback" /* BOOTPROTO_FALLBACK */
"none", /* IPv4PROTO_NONE */
"static", /* IPv4PROTO_STATIC */
"dhcp", /* IPv4PROTO_DHCP */
"fallback" /* IPv4PROTO_FALLBACK */
};
/****************************************************************************
@ -91,10 +91,10 @@ static void ipcfg_dump_addr(FAR const char *variable, in_addr_t address)
static int ipcfg_dump_config(FAR const char *netdev)
{
struct ipcfg_s ipcfg;
struct ipv4cfg_s ipv4cfg;
int ret;
ret = ipcfg_read(netdev, &ipcfg);
ret = ipcfg_read(netdev, (FAR struct ipcfg_s *)&ipv4cfg, AF_INET);
if (ret < 0)
{
fprintf(stderr, "ERROR: ipcfg_read() failed: %d\n", ret);
@ -105,19 +105,19 @@ static int ipcfg_dump_config(FAR const char *netdev)
printf("%s:\n", netdev);
if (ipcfg.proto > BOOTPROTO_MAX)
if (ipv4cfg.proto > IPv4PROTO_MAX)
{
printf("BOOTPROTO: %d [INVALID]\n", ipcfg.proto);
printf("BOOTPROTO: %d [INVALID]\n", ipv4cfg.proto);
}
else
{
printf("BOOTPROTO: %s\n", g_proto_name[ipcfg.proto]);
printf("BOOTPROTO: %s\n", g_ipv4proto_name[ipv4cfg.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);
ipcfg_dump_addr("IPADDR: ", ipv4cfg.ipaddr);
ipcfg_dump_addr("NETMASK: ", ipv4cfg.netmask);
ipcfg_dump_addr("ROUTER: ", ipv4cfg.router);
ipcfg_dump_addr("DNS: ", ipv4cfg.dnsaddr);
return OK;
}
@ -128,19 +128,19 @@ static int ipcfg_dump_config(FAR const char *netdev)
static int ipcfg_write_config(FAR const char *netdev)
{
struct ipcfg_s ipcfg;
struct ipv4cfg_s ipv4cfg;
int ret;
ipcfg.proto = BOOTPROTO_DHCP;
ipcfg.ipaddr = HTONL(0x0a000002);
ipcfg.netmask = HTONL(0xffffff00);
ipcfg.router = HTONL(0x0a000001);
ipcfg.router = HTONL(0x0a000003);
ipv4cfg.proto = IPv4PROTO_DHCP;
ipv4cfg.ipaddr = HTONL(0x0a000002);
ipv4cfg.netmask = HTONL(0xffffff00);
ipv4cfg.router = HTONL(0x0a000001);
ipv4cfg.dnsaddr = HTONL(0x0a000003);
ret = ipcfg_write(netdev, &ipcfg);
ret = ipcfg_write(netdev, (FAR struct ipcfg_s *)&ipv4cfg, AF_INET);
if (ret < 0)
{
fprintf(stderr, "ERROR: ipcfg_read() ipcfg_write: %d\n", ret);
fprintf(stderr, "ERROR: ipcfg_write() ipcfg_write: %d\n", ret);
}
return ret;

View File

@ -40,19 +40,33 @@
****************************************************************************/
#define MAX_LINESIZE 80
#define MAX_BOOTPROTO BOOTPROTO_FALLBACK
#define MAX_IPv4PROTO IPv4PROTO_FALLBACK
/* Values for the record type field */
/****************************************************************************
* Private 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 */
};
/****************************************************************************
* Private Data
****************************************************************************/
#if defined(CONFIG_IPCFG_WRITABLE) && !defined(CONFIG_IPCFG_BINARY)
static const char *g_proto_name[] =
static const char *g_ipv4proto_name[] =
{
"none", /* BOOTPROTO_NONE */
"static", /* BOOTPROTO_STATIC */
"dhcp", /* BOOTPROTO_DHCP */
"fallback" /* BOOTPROTO_FALLBACK */
"none", /* IPv4PROTO_NONE */
"static", /* IPv4PROTO_STATIC */
"dhcp", /* IPv4PROTO_DHCP */
"fallback" /* IPv4PROTO_FALLBACK */
};
#endif
@ -321,7 +335,10 @@ static void ipcfg_putaddr(FAR FILE *stream, FAR const char *variable,
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - Pointer to a user provided location to receive the IP
* configuration.
* configuration. Refers to either struct ipv4cfg_s or
* ipv6cfg_s, depending on the value of af.
* 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
@ -329,14 +346,16 @@ static void ipcfg_putaddr(FAR FILE *stream, FAR const char *variable,
*
****************************************************************************/
int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
int ipcfg_read(FAR const char *netdev, FAR void *ipcfg, sa_family_t af)
{
#ifdef CONFIG_IPCFG_BINARY
FAR struct ipv4cfg_s *ipv4cfg = (FAR struct ipv4cfg_s *)ipcfg;
struct ipcfg_header_s hdr;
ssize_t nread;
int fd;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
DEBUGASSERT(netdev != NULL && ipv4cfg != NULL && af == AF_INET);
/* Open the file */
@ -346,15 +365,41 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
return fd;
}
/* Read the header */
nread = read(fd, &hdr, sizeof(struct ipcfg_header_s));
if (nread < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to read file: %d\n", ret);
goto errout_with_fd;
}
else if (nread != sizeof(struct ipcfg_header_s))
{
ret = -EIO;
fprintf(stderr, "ERROR: Bad read size: %ld\n", (long)nread);
goto errout_with_fd;
}
/* Verify the header. Only a single IPv4 header is anticipated */
if (hdr.next != 0 || hdr.type != AF_INET)
{
ret = -EINVAL;
fprintf(stderr, "ERROR: Bad header: {%u,%u}\n",
hdr.next, hdr.type);
goto errout_with_fd;
}
/* Read the file content */
nread = read(fd, ipcfg, sizeof(struct ipcfg_s));
nread = read(fd, ipv4cfg, sizeof(struct ipv4cfg_s));
if (nread < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to read file: %d\n", ret);
}
else if (nread != sizeof(struct ipcfg_s))
else if (nread != sizeof(struct ipv4cfg_s))
{
ret = -EIO;
fprintf(stderr, "ERROR: Bad read size: %ld\n", (long)nread);
@ -364,16 +409,18 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
ret = OK;
}
errout_with_fd:
close(fd);
return ret;
#else
FAR struct ipv4cfg_s *ipv4cfg = (FAR struct ipv4cfg_s *)ipcfg;
FAR FILE *stream;
char line[MAX_LINESIZE];
int index;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
DEBUGASSERT(netdev != NULL && ipv4cfg != NULL && af == AF_INET);
/* Open the file */
@ -385,7 +432,7 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
/* Process each line in the file */
memset(ipcfg, 0, sizeof(FAR struct ipcfg_s));
memset(ipv4cfg, 0, sizeof(FAR struct ipv4cfg_s));
while (fgets(line, MAX_LINESIZE, stream) != NULL)
{
@ -426,45 +473,45 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
variable, value);
}
}
else if (strcmp(variable, "BOOTPROTO") == 0)
else if (strcmp(variable, "IPv4PROTO") == 0)
{
if (strcmp(value, "none") == 0)
{
ipcfg->proto = BOOTPROTO_NONE;
ipv4cfg->proto = IPv4PROTO_NONE;
}
else if (strcmp(value, "static") == 0)
{
ipcfg->proto = BOOTPROTO_STATIC;
ipv4cfg->proto = IPv4PROTO_STATIC;
}
else if (strcmp(value, "dhcp") == 0)
{
ipcfg->proto = BOOTPROTO_DHCP;
ipv4cfg->proto = IPv4PROTO_DHCP;
}
else if (strcmp(value, "fallback") == 0)
{
ipcfg->proto = BOOTPROTO_FALLBACK;
ipv4cfg->proto = IPv4PROTO_FALLBACK;
}
else
{
fprintf(stderr, "ERROR: Unrecognized BOOTPROTO: %s=%s\n",
fprintf(stderr, "ERROR: Unrecognized IPv4PROTO: %s=%s\n",
variable, value);
}
}
else if (strcmp(variable, "IPADDR") == 0)
else if (strcmp(variable, "IPv4IPADDR") == 0)
{
ipcfg->ipaddr = inet_addr(value);
ipv4cfg->ipaddr = inet_addr(value);
}
else if (strcmp(variable, "NETMASK") == 0)
else if (strcmp(variable, "IPv4NETMASK") == 0)
{
ipcfg->netmask = inet_addr(value);
ipv4cfg->netmask = inet_addr(value);
}
else if (strcmp(variable, "ROUTER") == 0)
else if (strcmp(variable, "IPv4ROUTER") == 0)
{
ipcfg->router = inet_addr(value);
ipv4cfg->router = inet_addr(value);
}
else if (strcmp(variable, "DNS") == 0)
else if (strcmp(variable, "IPv4DNS") == 0)
{
ipcfg->dnsaddr = inet_addr(value);
ipv4cfg->dnsaddr = inet_addr(value);
}
else
{
@ -489,7 +536,10 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - The IP configuration to be written.
* ipcfg - The IP configuration to be written. Refers to either struct
* ipv4cfg_s or ipv6cfg_s, depending on the value of af.
* af - Identifies the address family whose IP configuration is
* to be written. May be either AF_INET or AF_INET6.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
@ -498,14 +548,17 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg)
****************************************************************************/
#ifdef CONFIG_IPCFG_WRITABLE
int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg)
int ipcfg_write(FAR const char *netdev, FAR const void *ipcfg,
sa_family_t af)
{
#ifdef CONFIG_IPCFG_BINARY
FAR struct ipv4cfg_s *ipv4cfg = (FAR struct ipv4cfg_s *)ipcfg;
struct ipcfg_header_s hdr;
ssize_t nwritten;
int fd;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
DEBUGASSERT(netdev != NULL && ipv4cfg != NULL && af == AF_INET);
/* Open the file */
@ -515,15 +568,34 @@ int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg)
return fd;
}
/* Write the file header */
hdr.next = 0;
hdr.type = AF_INET;
nwritten = write(fd, &hdr, sizeof(struct ipcfg_header_s));
if (nwritten < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to write to file: %d\n", ret);
goto errout_with_fd;
}
else if (nwritten != sizeof(struct ipcfg_header_s))
{
ret = -EIO;
fprintf(stderr, "ERROR: Bad write size: %ld\n", (long)nwritten);
goto errout_with_fd;
}
/* Write the file content */
nwritten = write(fd, ipcfg, sizeof(struct ipcfg_s));
nwritten = write(fd, ipv4cfg, sizeof(struct ipv4cfg_s));
if (nwritten < 0)
{
ret = -errno;
fprintf(stderr, "ERROR: Failed to write file: %d\n", ret);
}
else if (nwritten != sizeof(struct ipcfg_s))
else if (nwritten != sizeof(struct ipv4cfg_s))
{
ret = -EIO;
fprintf(stderr, "ERROR: Bad write size: %ld\n", (long)nwritten);
@ -533,14 +605,16 @@ int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg)
ret = OK;
}
errout_with_fd:
close(fd);
return ret;
#else
FAR struct ipv4cfg_s *ipv4cfg = (FAR struct ipv4cfg_s *)ipcfg;
FAR FILE *stream;
int ret;
DEBUGASSERT(netdev != NULL && ipcfg != NULL);
DEBUGASSERT(netdev != NULL && ipv4cfg != NULL && af == AF_INET);
/* Open the file */
@ -552,20 +626,20 @@ int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg)
/* Format and write the file */
if ((unsigned)ipcfg->proto > MAX_BOOTPROTO)
if ((unsigned)ipv4cfg->proto > MAX_IPv4PROTO)
{
fprintf(stderr, "ERROR: Unrecognized BOOTPROTO value: %d\n",
ipcfg->proto);
fprintf(stderr, "ERROR: Unrecognized IPv4PROTO value: %d\n",
ipv4cfg->proto);
return -EINVAL;
}
fprintf(stream, "DEVICE=%s\n", netdev);
fprintf(stream, "BOOTPROTO=%s\n", g_proto_name[ipcfg->proto]);
fprintf(stream, "IPv4PROTO=%s\n", g_ipv4proto_name[ipv4cfg->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);
ipcfg_putaddr(stream, "IPv4IPADDR", ipv4cfg->ipaddr);
ipcfg_putaddr(stream, "IPv4NETMASK", ipv4cfg->netmask);
ipcfg_putaddr(stream, "IPv4ROUTER", ipv4cfg->router);
ipcfg_putaddr(stream, "IPv4DNS", ipv4cfg->dnsaddr);
/* Close the file and return */

View File

@ -31,23 +31,17 @@
* 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:
*
* Common Settings:
*
* DEVICE=name
* where name is the name of the physical device.
*
* BOOTPROTO=protocol
* IPv4 Settings:
*
* IPv4BOOTPROTO=protocol
* where protocol is one of the following:
*
* none - No protocol selected
@ -58,25 +52,35 @@ enum ipcfg_bootproto_e
* 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
* IPv4ADDR=address
* where address is the IPv4 address. Used only with static or fallback
* protocols.
*
* NETMASK=address
* IPv4NETMASK=address
* where address is the netmask. Used only with static or fallback
* protocols.
*
* ROUTER=address
* IPv4ROUTER=address
* where address is the IPv4 default router address. Used only with
* static or fallback protocols.
*
* DNS=address
* IPv4DNS=address
* where address is a (optional) name server address.
*/
struct ipcfg_s
/* Values for the IPv4BOOTPROTO setting */
enum ipv4cfg_bootproto_e
{
enum ipcfg_bootproto_e proto; /* Configure for static and/or DHCP */
IPv4PROTO_NONE = 0, /* No protocol assigned */
IPv4PROTO_STATIC = 1, /* Use static IP */
IPv4PROTO_DHCP = 2, /* Use DHCP */
IPv4PROTO_FALLBACK = 3 /* Use DHCP with fall back static IP */
};
struct ipv4cfg_s
{
enum ipv4cfg_bootproto_e proto; /* Configure for static and/or DHCP */
/* The following fields are required for static/fallback configurations */
@ -89,6 +93,53 @@ struct ipcfg_s
in_addr_t dnsaddr; /* Name server address */
};
/* IPv6 Settings:
*
* IPv6BOOTPROTO=protocol
* where protocol is one of the following:
*
* none - No protocol selected
* static - Use static IP
* autoconf - ICMPv6 auto-configuration should be used
* fallback - Use auto-configuration 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:
*
* IPv6ADDR=address
* where address is the IPv6 address. Used only with static or fallback
* protocols.
*
* IPv6NETMASK=address
* where address is the netmask. Used only with static or fallback
* protocols.
*
* IPv6ROUTER=address
* where address is the IPv6 default router address. Used only with
* static or fallback protocols.
*/
/* Values for the IPv6BOOTPROTO setting */
enum ipv6cfg_bootproto_e
{
BOOTPROTO_NONE = 0, /* No protocol assigned */
BOOTPROTO_STATIC = 1, /* Use static IP */
BOOTPROTO_AUTOCONF = 2, /* Use ICMPv6 auto-configuration */
BOOTPROTO_FALLBACK = 3 /* Use auto-configuration with fall back static IP */
};
struct ipv6cfg_s
{
enum ipv6cfg_bootproto_e proto; /* Configure for static and/or autoconfig */
/* The following fields are required for static/fallback configurations */
struct in6_addr ipaddr; /* IPv6 address */
struct in6_addr netmask; /* Network mask */
struct in6_addr router; /* Default router */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@ -110,7 +161,10 @@ extern "C"
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - Pointer to a user provided location to receive the IP
* configuration.
* configuration. Refers to either struct ipv4cfg_s or
* ipv6cfg_s, depending on the value of af.
* 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
@ -118,7 +172,7 @@ extern "C"
*
****************************************************************************/
int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg);
int ipcfg_read(FAR const char *netdev, FAR void *ipcfg, sa_family_t af);
/****************************************************************************
* Name: ipcfg_write
@ -128,7 +182,10 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg);
*
* Input Parameters:
* netdev - The network device. For examplel "eth0"
* ipcfg - The IP configuration to be written.
* ipcfg - The IP configuration to be written. Refers to either struct
* ipv4cfg_s or ipv6cfg_s, depending on the value of af.
* af - Identifies the address family whose IP configuration is
* to be written. May be either AF_INET or AF_INET6.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
@ -137,7 +194,8 @@ int ipcfg_read(FAR const char *netdev, FAR struct ipcfg_s *ipcfg);
****************************************************************************/
#ifdef CONFIG_IPCFG_WRITABLE
int ipcfg_write(FAR const char *netdev, FAR const struct ipcfg_s *ipcfg);
int ipcfg_write(FAR const char *netdev, FAR const void *ipcfg,
sa_family_t af);
#endif
#undef EXTERN
#ifdef __cplusplus