Contiki-NG
Loading...
Searching...
No Matches
uipbuf.c
1/*
2 * Copyright (c) 2017, RISE SICS, Yanzi Networks
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the authors may not be used to endorse or promote
14 * products derived from this software without specific prior
15 * written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 * DAMAGE.
29 *
30 *
31 */
32#include "contiki.h"
33#include "net/ipv6/uip.h"
34#include "net/ipv6/uipbuf.h"
35#include <string.h>
36
37/*---------------------------------------------------------------------------*/
38
39static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX];
40static uint16_t uipbuf_default_attrs[UIPBUF_ATTR_MAX];
41
42/*---------------------------------------------------------------------------*/
43void
44uipbuf_clear(void)
45{
46 uip_len = 0;
47 uip_ext_len = 0;
49 uipbuf_clear_attr();
50}
51/*---------------------------------------------------------------------------*/
52bool
53uipbuf_add_ext_hdr(int16_t len)
54{
55 if(len + uip_len <= UIP_LINK_MTU && len + uip_len >= 0 && len + uip_ext_len >= 0) {
56 uip_ext_len += len;
57 uip_len += len;
58 return true;
59 } else {
60 return false;
61 }
62}
63/*---------------------------------------------------------------------------*/
64bool
65uipbuf_set_len(uint16_t len)
66{
67 if(len <= UIP_LINK_MTU) {
68 uip_len = len;
69 return true;
70 } else {
71 return false;
72 }
73}
74/*---------------------------------------------------------------------------*/
75void
76uipbuf_set_len_field(struct uip_ip_hdr *hdr, uint16_t len)
77{
78 hdr->len[0] = (len >> 8);
79 hdr->len[1] = (len & 0xff);
80}
81/*---------------------------------------------------------------------------*/
82uint16_t
83uipbuf_get_len_field(struct uip_ip_hdr *hdr)
84{
85 return ((uint16_t)(hdr->len[0]) << 8) + hdr->len[1];
86}
87/*---------------------------------------------------------------------------*/
88/* Get the next header given the buffer - start indicates that this is
89 start of the IPv6 header - needs to be set to 0 when in an ext hdr */
90uint8_t *
91uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, bool start)
92{
93 int curr_hdr_len = 0;
94 int next_hdr_len = 0;
95 uint8_t *next_header = NULL;
96 struct uip_ip_hdr *ipbuf = NULL;
97 struct uip_ext_hdr *curr_ext = NULL;
98 struct uip_ext_hdr *next_ext = NULL;
99
100 if(start) {
101 /* protocol in the IP buffer */
102 ipbuf = (struct uip_ip_hdr *)buffer;
103 *protocol = ipbuf->proto;
104 curr_hdr_len = UIP_IPH_LEN;
105 } else {
106 /* protocol in the Ext hdr */
107 curr_ext = (struct uip_ext_hdr *)buffer;
108 *protocol = curr_ext->next;
109 /* This is just an ext header */
110 curr_hdr_len = (curr_ext->len << 3) + 8;
111 }
112
113 /* Check first if enough space for current header */
114 if(curr_hdr_len > size) {
115 return NULL;
116 }
117 next_header = buffer + curr_hdr_len;
118
119 /* Check if the buffer is large enough for the next header */
120 if(uip_is_proto_ext_hdr(*protocol)) {
121 if(curr_hdr_len + sizeof(struct uip_ext_hdr) > size) {
122 return NULL;
123 }
124 next_ext = (struct uip_ext_hdr *)next_header;
125 next_hdr_len = (next_ext->len << 3) + 8;
126 } else {
127 if(*protocol == UIP_PROTO_TCP) {
128 next_hdr_len = UIP_TCPH_LEN;
129 } else if(*protocol == UIP_PROTO_UDP) {
130 next_hdr_len = UIP_UDPH_LEN;
131 } else if(*protocol == UIP_PROTO_ICMP6) {
132 next_hdr_len = UIP_ICMPH_LEN;
133 }
134 }
135
136 /* Size must be enough to hold both the current and next header */
137 if(next_hdr_len == 0 || curr_hdr_len + next_hdr_len > size) {
138 return NULL;
139 }
140
141 return next_header;
142}
143/*---------------------------------------------------------------------------*/
144/* Get the final header given the buffer - that is assumed to be at start
145 of an IPv6 header */
146uint8_t *
147uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol)
148{
149 uint8_t *nbuf;
150
151 nbuf = uipbuf_get_next_header(buffer, size, protocol, true);
152 while(nbuf != NULL && uip_is_proto_ext_hdr(*protocol)) {
153 /* move to the ext hdr */
154 nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), protocol, false);
155 }
156
157 /* In case the buffer wasn't large enough for all headers, return NULL */
158 return nbuf;
159}
160/*---------------------------------------------------------------------------*/
161uint8_t *
162uipbuf_search_header(uint8_t *buffer, uint16_t size, uint8_t protocol)
163{
164 uint8_t *nbuf;
165 uint8_t next_proto;
166
167 nbuf = uipbuf_get_next_header(buffer, size, &next_proto, true);
168 while(nbuf != NULL && next_proto != protocol && uip_is_proto_ext_hdr(next_proto)) {
169 /* move to the ext hdr */
170 nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), &next_proto, false);
171 }
172
173 if(next_proto == protocol) {
174 return nbuf;
175 } else {
176 return NULL;
177 }
178}
179/*---------------------------------------------------------------------------*/
180/**
181 * Common functions for uipbuf (attributes, etc).
182 *
183 */
184/*---------------------------------------------------------------------------*/
185uint16_t
186uipbuf_get_attr(uint8_t type)
187{
188 if(type < UIPBUF_ATTR_MAX) {
189 return uipbuf_attrs[type];
190 }
191 return 0;
192}
193/*---------------------------------------------------------------------------*/
194int
195uipbuf_set_attr(uint8_t type, uint16_t value)
196{
197 if(type < UIPBUF_ATTR_MAX) {
198 uipbuf_attrs[type] = value;
199 return 1;
200 }
201 return 0;
202}
203/*---------------------------------------------------------------------------*/
204int
205uipbuf_set_default_attr(uint8_t type, uint16_t value)
206{
207 if(type < UIPBUF_ATTR_MAX) {
208 uipbuf_default_attrs[type] = value;
209 return 1;
210 }
211 return 0;
212}
213/*---------------------------------------------------------------------------*/
214void
215uipbuf_clear_attr(void)
216{
217 /* set everything to "defaults" */
218 memcpy(uipbuf_attrs, uipbuf_default_attrs, sizeof(uipbuf_attrs));
219}
220/*---------------------------------------------------------------------------*/
221void
222uipbuf_set_attr_flag(uint16_t flag)
223{
224 /* Assume only 16-bits for flags now */
225 uipbuf_attrs[UIPBUF_ATTR_FLAGS] |= flag;
226}
227/*---------------------------------------------------------------------------*/
228void
229uipbuf_clr_attr_flag(uint16_t flag)
230{
231 uipbuf_attrs[UIPBUF_ATTR_FLAGS] &= ~flag;
232}
233/*---------------------------------------------------------------------------*/
234uint16_t
235uipbuf_is_attr_flag(uint16_t flag)
236{
237 return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag;
238}
239/*---------------------------------------------------------------------------*/
240void
241uipbuf_init(void)
242{
243 memset(uipbuf_default_attrs, 0, sizeof(uipbuf_default_attrs));
244 /* And initialize anything that should be initialized */
245 uipbuf_set_default_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS,
247 /* set the not-set default value - this will cause the MAC layer to
248 configure its default */
249 uipbuf_set_default_attr(UIPBUF_ATTR_LLSEC_LEVEL,
250 UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT);
251}
252
253/*---------------------------------------------------------------------------*/
static void start(void)
Start measurement.
uint16_t uip_ext_len
The length of the extension headers.
Definition uip6.c:122
uint16_t uip_len
The length of the packet in the uip_buf buffer.
Definition uip6.c:159
uint8_t uip_last_proto
The final protocol after IPv6 extension headers: UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6.
Definition uip6.c:125
#define UIP_LINK_MTU
The maximum transmission unit at the IP Layer.
Definition uipopt.h:154
#define UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED
This is the default value of MAC-layer transmissons for uIPv6.
Definition uipopt.h:445
Header file for the uIP TCP/IP stack.