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 /*---------------------------------------------------------------------------*/
59 int
60 uiplib_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. */
123 int
124 uiplib_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 /*---------------------------------------------------------------------------*/
157 void
158 uiplib_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 /*---------------------------------------------------------------------------*/
165 int
166 uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
167 {
168  uint16_t a;
169  unsigned int i;
170  int f;
171  int n = 0;
172 
173  if(size == 0) {
174  return 0;
175  }
176 
177  if(addr == NULL) {
178  n = snprintf(buf, size, "(NULL IP addr)");
179  return n;
180  } else if(ip64_addr_is_ipv4_mapped_addr(addr)) {
181  /*
182  * Printing IPv4-mapped addresses is done according to RFC 4291 [1]
183  *
184  * "An alternative form that is sometimes more
185  * convenient when dealing with a mixed environment
186  * of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d,
187  * where the 'x's are the hexadecimal values of the
188  * six high-order 16-bit pieces of the address, and
189  * the 'd's are the decimal values of the four
190  * low-order 8-bit pieces of the address (standard
191  * IPv4 representation)."
192  *
193  * [1] https://tools.ietf.org/html/rfc4291#page-4
194  */
195  n = snprintf(buf, size, "::FFFF:%u.%u.%u.%u", addr->u8[12],
196  addr->u8[13], addr->u8[14], addr->u8[15]);
197  return n;
198  } else {
199  for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
200  a = (addr->u8[i] << 8) + addr->u8[i + 1];
201  if(a == 0 && f >= 0) {
202  if(f++ == 0) {
203  n += snprintf(buf+n, size-n, "::");
204  if(n >= size) {
205  return n;
206  }
207  }
208  } else {
209  if(f > 0) {
210  f = -1;
211  } else if(i > 0) {
212  n += snprintf(buf+n, size-n, ":");
213  if(n >= size) {
214  return n;
215  }
216  }
217  n += snprintf(buf+n, size-n, "%x", a);
218  if(n >= size) {
219  return n;
220  }
221  }
222  }
223  }
224  return n;
225 }
226 /*---------------------------------------------------------------------------*/
227 /**
228  * @}
229  */
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
Representation of an IP address.
Definition: uip.h:95
Header file for the IP address manipulation library.
Header file for the uIP TCP/IP stack.
void uiplib_ipaddr_print(const uip_ipaddr_t *addr)
Print an IP address using printf().
Definition: uiplib.c:158
Header file for the logging system
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