Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nanostack-libservice by
source/libip6string/stoip6.c@1:84b8bb258055, 2016-01-22 (annotated)
- Committer:
- Christopher Haster
- Date:
- Fri Jan 22 16:48:50 2016 -0600
- Revision:
- 1:84b8bb258055
Initial move of nanostack-libservice to mercurial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Christopher Haster |
1:84b8bb258055 | 1 | /* |
Christopher Haster |
1:84b8bb258055 | 2 | * Copyright (c) 2014-2015 ARM Limited. All rights reserved. |
Christopher Haster |
1:84b8bb258055 | 3 | * SPDX-License-Identifier: Apache-2.0 |
Christopher Haster |
1:84b8bb258055 | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
Christopher Haster |
1:84b8bb258055 | 5 | * not use this file except in compliance with the License. |
Christopher Haster |
1:84b8bb258055 | 6 | * You may obtain a copy of the License at |
Christopher Haster |
1:84b8bb258055 | 7 | * |
Christopher Haster |
1:84b8bb258055 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
Christopher Haster |
1:84b8bb258055 | 9 | * |
Christopher Haster |
1:84b8bb258055 | 10 | * Unless required by applicable law or agreed to in writing, software |
Christopher Haster |
1:84b8bb258055 | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
Christopher Haster |
1:84b8bb258055 | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Christopher Haster |
1:84b8bb258055 | 13 | * See the License for the specific language governing permissions and |
Christopher Haster |
1:84b8bb258055 | 14 | * limitations under the License. |
Christopher Haster |
1:84b8bb258055 | 15 | */ |
Christopher Haster |
1:84b8bb258055 | 16 | #include <string.h> |
Christopher Haster |
1:84b8bb258055 | 17 | #include <stdlib.h> |
Christopher Haster |
1:84b8bb258055 | 18 | #include <stdint.h> |
Christopher Haster |
1:84b8bb258055 | 19 | #include "common_functions.h" |
Christopher Haster |
1:84b8bb258055 | 20 | #include "ip6string.h" |
Christopher Haster |
1:84b8bb258055 | 21 | |
Christopher Haster |
1:84b8bb258055 | 22 | static uint16_t hex(const char *p); |
Christopher Haster |
1:84b8bb258055 | 23 | |
Christopher Haster |
1:84b8bb258055 | 24 | /** |
Christopher Haster |
1:84b8bb258055 | 25 | * Convert numeric IPv6 address string to a binary. |
Christopher Haster |
1:84b8bb258055 | 26 | * IPv4 tunnelling addresses are not covered. |
Christopher Haster |
1:84b8bb258055 | 27 | * \param ip6addr IPv6 address in string format. |
Christopher Haster |
1:84b8bb258055 | 28 | * \param len Length of ipv6 string. |
Christopher Haster |
1:84b8bb258055 | 29 | * \param dest buffer for address. MUST be 16 bytes. |
Christopher Haster |
1:84b8bb258055 | 30 | */ |
Christopher Haster |
1:84b8bb258055 | 31 | void stoip6(const char *ip6addr, size_t len, void *dest) |
Christopher Haster |
1:84b8bb258055 | 32 | { |
Christopher Haster |
1:84b8bb258055 | 33 | uint8_t *addr; |
Christopher Haster |
1:84b8bb258055 | 34 | const char *p, *q; |
Christopher Haster |
1:84b8bb258055 | 35 | int_fast8_t field_no, coloncolon = -1; |
Christopher Haster |
1:84b8bb258055 | 36 | |
Christopher Haster |
1:84b8bb258055 | 37 | addr = dest; |
Christopher Haster |
1:84b8bb258055 | 38 | |
Christopher Haster |
1:84b8bb258055 | 39 | if (len > 39) { // Too long, not possible. We do not support IPv4-mapped IPv6 addresses |
Christopher Haster |
1:84b8bb258055 | 40 | return; |
Christopher Haster |
1:84b8bb258055 | 41 | } |
Christopher Haster |
1:84b8bb258055 | 42 | |
Christopher Haster |
1:84b8bb258055 | 43 | // First go forward the string, until end, noting :: position if any |
Christopher Haster |
1:84b8bb258055 | 44 | for (field_no = 0, p = ip6addr; (len > (p - ip6addr)) && *p && field_no < 8; p = q + 1) { |
Christopher Haster |
1:84b8bb258055 | 45 | q = p; |
Christopher Haster |
1:84b8bb258055 | 46 | // Seek for ':' or end |
Christopher Haster |
1:84b8bb258055 | 47 | while (*q && (*q != ':')) { |
Christopher Haster |
1:84b8bb258055 | 48 | q++; |
Christopher Haster |
1:84b8bb258055 | 49 | } |
Christopher Haster |
1:84b8bb258055 | 50 | //Convert and write this part, (high-endian AKA network byte order) |
Christopher Haster |
1:84b8bb258055 | 51 | addr = common_write_16_bit(hex(p), addr); |
Christopher Haster |
1:84b8bb258055 | 52 | field_no++; |
Christopher Haster |
1:84b8bb258055 | 53 | //Check if we reached "::" |
Christopher Haster |
1:84b8bb258055 | 54 | if ((len > (q - ip6addr)) && *q && (q[0] == ':') && (q[1] == ':')) { |
Christopher Haster |
1:84b8bb258055 | 55 | coloncolon = field_no; |
Christopher Haster |
1:84b8bb258055 | 56 | q++; |
Christopher Haster |
1:84b8bb258055 | 57 | } |
Christopher Haster |
1:84b8bb258055 | 58 | } |
Christopher Haster |
1:84b8bb258055 | 59 | |
Christopher Haster |
1:84b8bb258055 | 60 | if (coloncolon != -1) { |
Christopher Haster |
1:84b8bb258055 | 61 | /* Insert zeros in the appropriate place */ |
Christopher Haster |
1:84b8bb258055 | 62 | uint_fast8_t head_size = 2 * coloncolon; |
Christopher Haster |
1:84b8bb258055 | 63 | uint_fast8_t inserted_size = 2 * (8 - field_no); |
Christopher Haster |
1:84b8bb258055 | 64 | uint_fast8_t tail_size = 16 - head_size - inserted_size; |
Christopher Haster |
1:84b8bb258055 | 65 | addr = dest; |
Christopher Haster |
1:84b8bb258055 | 66 | memmove(addr + head_size + inserted_size, addr + head_size, tail_size); |
Christopher Haster |
1:84b8bb258055 | 67 | memset(addr + head_size, 0, inserted_size); |
Christopher Haster |
1:84b8bb258055 | 68 | } else if (field_no != 8) { |
Christopher Haster |
1:84b8bb258055 | 69 | /* Should really report an error if we didn't get 8 fields */ |
Christopher Haster |
1:84b8bb258055 | 70 | memset(addr, 0, 16 - field_no * 2); |
Christopher Haster |
1:84b8bb258055 | 71 | } |
Christopher Haster |
1:84b8bb258055 | 72 | } |
Christopher Haster |
1:84b8bb258055 | 73 | unsigned char sipv6_prefixlength(const char *ip6addr) |
Christopher Haster |
1:84b8bb258055 | 74 | { |
Christopher Haster |
1:84b8bb258055 | 75 | char *ptr = strchr(ip6addr, '/'); |
Christopher Haster |
1:84b8bb258055 | 76 | if (ptr) { |
Christopher Haster |
1:84b8bb258055 | 77 | return (unsigned char)strtoul(ptr + 1, 0, 10); |
Christopher Haster |
1:84b8bb258055 | 78 | } |
Christopher Haster |
1:84b8bb258055 | 79 | return 0; |
Christopher Haster |
1:84b8bb258055 | 80 | } |
Christopher Haster |
1:84b8bb258055 | 81 | static uint16_t hex(const char *p) |
Christopher Haster |
1:84b8bb258055 | 82 | { |
Christopher Haster |
1:84b8bb258055 | 83 | uint16_t val = 0; |
Christopher Haster |
1:84b8bb258055 | 84 | |
Christopher Haster |
1:84b8bb258055 | 85 | for (;;) { |
Christopher Haster |
1:84b8bb258055 | 86 | char c = *p++; |
Christopher Haster |
1:84b8bb258055 | 87 | if ((c >= '0') && (c <= '9')) { |
Christopher Haster |
1:84b8bb258055 | 88 | val = (val << 4) | (c - '0'); |
Christopher Haster |
1:84b8bb258055 | 89 | } else if ((c >= 'A') && (c <= 'F')) { |
Christopher Haster |
1:84b8bb258055 | 90 | val = (val << 4) | (10 + (c - 'A')); |
Christopher Haster |
1:84b8bb258055 | 91 | } else if ((c >= 'a') && (c <= 'f')) { |
Christopher Haster |
1:84b8bb258055 | 92 | val = (val << 4) | (10 + (c - 'a')); |
Christopher Haster |
1:84b8bb258055 | 93 | } else { |
Christopher Haster |
1:84b8bb258055 | 94 | break; // Non hex character |
Christopher Haster |
1:84b8bb258055 | 95 | } |
Christopher Haster |
1:84b8bb258055 | 96 | } |
Christopher Haster |
1:84b8bb258055 | 97 | return val; |
Christopher Haster |
1:84b8bb258055 | 98 | } |