Contiki-NG
uiplib.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of
3 * Computer Science.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior
16 * written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * This file is part of the uIP TCP/IP stack and the Contiki operating system.
31 *
32 *
33 */
34
35/**
36 * \addtogroup uip-addr-lib
37 * @{
38 *
39 * \file
40 * Implementation of the IP address manipulation library
41 * \author
42 * Nicolas Tsiftes <nvt@sics.se>
43 * Niclas Finne <nfi@sics.se>
44 * Joakim Eriksson <joakime@sics.se>
45 */
46
47#include "net/ipv6/uip.h"
48#include "net/ipv6/uiplib.h"
49#include "net/ipv6/ip64-addr.h"
50#include <string.h>
51#include <stdio.h>
52
53/* Log configuration */
54#include "sys/log.h"
55#define LOG_MODULE "uiplib"
56#define LOG_LEVEL LOG_LEVEL_NONE
57
58/*---------------------------------------------------------------------------*/
59int
60uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
61{
62 uint16_t value;
63 int tmp, zero;
64 unsigned int len;
65 char c = 0; //gcc warning if not initialized
66
67 value = 0;
68 zero = -1;
69 if(*addrstr == '[') addrstr++;
70
71 for(len = 0; len < sizeof(uip_ip6addr_t) - 1; addrstr++) {
72 c = *addrstr;
73 if(c == ':' || c == '\0' || c == ']' || c == '/') {
74 ipaddr->u8[len] = (value >> 8) & 0xff;
75 ipaddr->u8[len + 1] = value & 0xff;
76 len += 2;
77 value = 0;
78
79 if(c == '\0' || c == ']' || c == '/') {
80 break;
81 }
82
83 if(*(addrstr + 1) == ':') {
84 /* Zero compression */
85 if(zero < 0) {
86 zero = len;
87 }
88 addrstr++;
89 }
90 } else {
91 if(c >= '0' && c <= '9') {
92 tmp = c - '0';
93 } else if(c >= 'a' && c <= 'f') {
94 tmp = c - 'a' + 10;
95 } else if(c >= 'A' && c <= 'F') {
96 tmp = c - 'A' + 10;
97 } else {
98 LOG_ERR("illegal char: '%c'\n", c);
99 return 0;
100 }
101 value = (value << 4) + (tmp & 0xf);
102 }
103 }
104 if(c != '\0' && c != ']' && c != '/') {
105 LOG_ERR("too large address\n");
106 return 0;
107 }
108 if(len < sizeof(uip_ip6addr_t)) {
109 if(zero < 0) {
110 LOG_ERR("too short address\n");
111 return 0;
112 }
113 memmove(&ipaddr->u8[zero + sizeof(uip_ip6addr_t) - len],
114 &ipaddr->u8[zero], len - zero);
115 memset(&ipaddr->u8[zero], 0, sizeof(uip_ip6addr_t) - len);
116 }
117
118 return 1;
119}
120/*---------------------------------------------------------------------------*/
121/* Parse a IPv4-address from a string. Returns the number of characters read
122 * for the address. */
123int
124uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr)
125{
126 unsigned char tmp;
127 char c;
128 unsigned char i, j;
129 uint8_t charsread = 0;
130
131 tmp = 0;
132
133 for(i = 0; i < 4; ++i) {
134 j = 0;
135 do {
136 c = *addrstr;
137 ++j;
138 if(j > 4) {
139 return 0;
140 }
141 if(c == '.' || c == 0 || c == ' ') {
142 ipaddr->u8[i] = tmp;
143 tmp = 0;
144 } else if(c >= '0' && c <= '9') {
145 tmp = (tmp * 10) + (c - '0');
146 } else {
147 return 0;
148 }
149 ++addrstr;
150 ++charsread;
151 } while(c != '.' && c != 0 && c != ' ');
152
153 }
154 return charsread - 1;
155}
156/*---------------------------------------------------------------------------*/
157void
158uiplib_ipaddr_print(const uip_ipaddr_t *addr)
159{
160 char buf[UIPLIB_IPV6_MAX_STR_LEN];
161 uiplib_ipaddr_snprint(buf, sizeof(buf), addr);
162 printf("%s", buf);
163}
164/*---------------------------------------------------------------------------*/
165int
166uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
167{
168 unsigned int n = 0;
169
170 if(size == 0) {
171 return 0;
172 }
173
174 if(addr == NULL) {
175 return snprintf(buf, size, "(NULL IP addr)");
176 } else if(ip64_addr_is_ipv4_mapped_addr(addr)) {
177 /*
178 * Printing IPv4-mapped addresses is done according to RFC 4291 [1]
179 *
180 * "An alternative form that is sometimes more
181 * convenient when dealing with a mixed environment
182 * of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d,
183 * where the 'x's are the hexadecimal values of the
184 * six high-order 16-bit pieces of the address, and
185 * the 'd's are the decimal values of the four
186 * low-order 8-bit pieces of the address (standard
187 * IPv4 representation)."
188 *
189 * [1] https://tools.ietf.org/html/rfc4291#page-4
190 */
191 return snprintf(buf, size, "::FFFF:%u.%u.%u.%u", addr->u8[12],
192 addr->u8[13], addr->u8[14], addr->u8[15]);
193 } else {
194 int f = 0;
195 for(size_t i = 0; i < sizeof(uip_ipaddr_t); i += 2) {
196 uint16_t a = (addr->u8[i] << 8) + addr->u8[i + 1];
197 if(a == 0 && f >= 0) {
198 if(f++ == 0) {
199 n += snprintf(buf+n, size-n, "::");
200 if(n >= size) {
201 return n;
202 }
203 }
204 } else {
205 if(f > 0) {
206 f = -1;
207 } else if(i > 0) {
208 n += snprintf(buf+n, size-n, ":");
209 if(n >= size) {
210 return n;
211 }
212 }
213 n += snprintf(buf+n, size-n, "%x", a);
214 if(n >= size) {
215 return n;
216 }
217 }
218 }
219 }
220 return n;
221}
222/*---------------------------------------------------------------------------*/
223/**
224 * @}
225 */
void uiplib_ipaddr_print(const uip_ipaddr_t *addr)
Print an IP address using printf().
Definition: uiplib.c:158
int uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
Write at most size - 1 characters of the IP address to the output string.
Definition: uiplib.c:166
Header file for the logging system.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:116
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
Header file for the uIP TCP/IP stack.
Header file for the IP address manipulation library.
Representation of an IP address.
Definition: uip.h:95