diff --git a/examples/ipcfg/ipcfg_main.c b/examples/ipcfg/ipcfg_main.c index 6107a50e1..c899b2df9 100644 --- a/examples/ipcfg/ipcfg_main.c +++ b/examples/ipcfg/ipcfg_main.c @@ -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; diff --git a/fsutils/ipcfg/ipcfg.c b/fsutils/ipcfg/ipcfg.c index b809dd733..34e62e374 100644 --- a/fsutils/ipcfg/ipcfg.c +++ b/fsutils/ipcfg/ipcfg.c @@ -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 */ diff --git a/include/fsutils/ipcfg.h b/include/fsutils/ipcfg.h index 5cbb140b7..63eaa2c40 100644 --- a/include/fsutils/ipcfg.h +++ b/include/fsutils/ipcfg.h @@ -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- 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