| /**************************************************************************** |
| * netutils/netlib/netlib_ipv6route.c |
| * |
| * Copyright (C) 2017 Gregory Nutt. All rights reserved. |
| * Author: Gregory Nutt <gnutt@nuttx.org> |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote |
| * products derived from this software without specific prior |
| * written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
| * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
| * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/config.h> |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <assert.h> |
| #include <errno.h> |
| |
| #include <arpa/inet.h> |
| |
| #include "netutils/netlib.h" |
| |
| #if defined(CONFIG_NET_IPv6) && defined(HAVE_ROUTE_PROCFS) |
| |
| /**************************************************************************** |
| * Pre-processor Definitions |
| ****************************************************************************/ |
| |
| /* Determines the size of an intermediate buffer that must be large enough |
| * to handle the longest line generated by this logic. |
| */ |
| |
| #define PROCFS_LINELEN 58 |
| |
| /* The form of the entry from the routing table file: |
| * |
| * 11111111112222222222333333333344444444445555 |
| * 12345678901234567890123456789012345678901234567890123 |
| * nnnn. target: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx |
| * netmask: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx |
| * router: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx |
| */ |
| |
| #define ADDR_OFFSET 15 |
| |
| /**************************************************************************** |
| * Private Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: set_nul_terminator |
| * |
| * Description: |
| * Make sure that the string is NUL terminated. |
| * |
| ****************************************************************************/ |
| |
| static void set_nul_terminator(FAR char *str) |
| { |
| /* The first non-hex character that is not ':' terminates the address */ |
| |
| while ((*str >= '0' && *str <= '9') || |
| (*str >= 'a' && *str <= 'f') || |
| (*str >= 'A' && *str <= 'F') || |
| *str == ':') |
| { |
| str++; |
| } |
| |
| *str = '\0'; |
| } |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: netlib_read_ipv6route |
| * |
| * Description: |
| * Read the next entry from the IPv6 routing table. |
| * |
| * Input Parameters: |
| * fd - The open file descriptor to the procfs' IPv6 routing table. |
| * route - The location to return that the next routing table entry. |
| * |
| * Returned Value: |
| * sizeof(struct netlib_ipv6_route_s) is returned on success. Zero is |
| * returned if the end of file is encountered. A negated errno value is |
| * returned on any failure. |
| * |
| ****************************************************************************/ |
| |
| ssize_t netlib_read_ipv6route(FILE *stream, |
| FAR struct netlib_ipv6_route_s *route) |
| { |
| char line[PROCFS_LINELEN]; |
| FAR char *addr; |
| int ret; |
| |
| DEBUGASSERT(stream != NULL && route != NULL); |
| |
| /* The form of the entries read from the routing table: |
| * |
| * 1111111111222222222233333333334444444444555 |
| * 1234567890123456789012345678901234567890123456789012 |
| * nnnn. target: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx |
| * netmask: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx |
| * router: xxxx:xxxx:xxxx:xxxxxxxx:xxxx:xxxx:xxxx |
| */ |
| |
| /* Read the first line from the file */ |
| |
| if (fgets(line, PROCFS_LINELEN, stream) == NULL) |
| { |
| /* End of file (or possibly a read error?) */ |
| |
| return 0; |
| } |
| |
| /* The first line of the group should consist of a number index */ |
| |
| if (line[0] < '0' || line[0] > 9) |
| { |
| return -EINVAL; |
| } |
| |
| /* Make certain that there is a NUL terminator */ |
| |
| line[PROCFS_LINELEN - 1] = '\0'; |
| |
| /* Convert the prefix address to binary */ |
| |
| addr = &line[ADDR_OFFSET]; |
| set_nul_terminator(addr); |
| |
| ret = inet_pton(AF_INET6, addr, &route->prefix); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| else if (ret == 0) |
| { |
| return -EINVAL; |
| } |
| |
| /* Read the second line from the file */ |
| |
| if (fgets(line, PROCFS_LINELEN, stream) == NULL) |
| { |
| /* End of file (or possibly a read error?) */ |
| |
| return 0; |
| } |
| |
| /* The second line of the group should not include an index */ |
| |
| if (line[0] != ' ') |
| { |
| return -EINVAL; |
| } |
| |
| /* Make certain that there is a NUL terminator */ |
| |
| line[PROCFS_LINELEN - 1] = '\0'; |
| |
| /* Convert the prefix address to binary */ |
| |
| addr = &line[ADDR_OFFSET]; |
| set_nul_terminator(addr); |
| |
| ret = inet_pton(AF_INET6, addr, &route->netmask); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| else if (ret == 0) |
| { |
| return -EINVAL; |
| } |
| |
| /* Read the third line from the file */ |
| |
| if (fgets(line, PROCFS_LINELEN, stream) == NULL) |
| { |
| /* End of file (or possibly a read error?) */ |
| |
| return 0; |
| } |
| |
| /* The third line of the group should not include an index */ |
| |
| if (line[0] != ' ') |
| { |
| return -EINVAL; |
| } |
| |
| /* Make certain that there is a NUL terminator */ |
| |
| line[PROCFS_LINELEN - 1] = '\0'; |
| |
| /* Convert the prefix address to binary */ |
| |
| addr = &line[ADDR_OFFSET]; |
| set_nul_terminator(addr); |
| |
| ret = inet_pton(AF_INET6, addr, &route->router); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| else if (ret == 0) |
| { |
| return -EINVAL; |
| } |
| |
| return sizeof(struct netlib_ipv6_route_s); |
| } |
| |
| #endif /* CONFIG_NET_IPv6 && HAVE_ROUTE_PROCFS */ |