ReactOS 0.4.16-dev-1041-g8b6907f
zepif.c
Go to the documentation of this file.
1
18/*
19 * Copyright (c) 2018 Simon Goldschmidt
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without modification,
23 * are permitted provided that the following conditions are met:
24 *
25 * 1. Redistributions of source code must retain the above copyright notice,
26 * this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright notice,
28 * this list of conditions and the following disclaimer in the documentation
29 * and/or other materials provided with the distribution.
30 * 3. The name of the author may not be used to endorse or promote products
31 * derived from this software without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
34 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
35 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
36 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
38 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
42 * OF SUCH DAMAGE.
43 *
44 * This file is part of the lwIP TCP/IP stack.
45 *
46 * Author: Simon Goldschmidt <goldsimon@gmx.de>
47 *
48 */
49
50#include "netif/zepif.h"
51
52#if LWIP_IPV6 && LWIP_UDP
53
54#include "netif/lowpan6.h"
55#include "lwip/udp.h"
56#include "lwip/timeouts.h"
57#include <string.h>
58
60#ifndef ZEPIF_LOOPBACK
61#define ZEPIF_LOOPBACK 0
62#endif
63
64#define ZEP_MAX_DATA_LEN 127
65
66#ifdef PACK_STRUCT_USE_INCLUDES
67# include "arch/bpstruct.h"
68#endif
70struct zep_hdr {
71 PACK_STRUCT_FLD_8(u8_t prot_id[2]);
72 PACK_STRUCT_FLD_8(u8_t prot_version);
74 PACK_STRUCT_FLD_8(u8_t channel_id);
75 PACK_STRUCT_FIELD(u16_t device_id);
76 PACK_STRUCT_FLD_8(u8_t crc_mode);
77 PACK_STRUCT_FLD_8(u8_t unknown_1);
79 PACK_STRUCT_FIELD(u32_t seq_num);
80 PACK_STRUCT_FLD_8(u8_t unknown_2[10]);
84#ifdef PACK_STRUCT_USE_INCLUDES
85# include "arch/epstruct.h"
86#endif
87
88struct zepif_state {
89 struct zepif_init init;
90 struct udp_pcb *pcb;
91 u32_t seqno;
92};
93
94static u8_t zep_lowpan_timer_running;
95
96/* Helper function that calls the 6LoWPAN timer and reschedules itself */
97static void
98zep_lowpan_timer(void *arg)
99{
100 lowpan6_tmr();
101 if (zep_lowpan_timer_running) {
102 sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, arg);
103 }
104}
105
106/* Pass received pbufs into 6LowPAN netif */
107static void
108zepif_udp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
109 const ip_addr_t *addr, u16_t port)
110{
111 err_t err;
112 struct netif *netif_lowpan6 = (struct netif *)arg;
113 struct zep_hdr *zep;
114
115 LWIP_ASSERT("arg != NULL", arg != NULL);
116 LWIP_ASSERT("pcb != NULL", pcb != NULL);
117 LWIP_UNUSED_ARG(pcb); /* for LWIP_NOASSERT */
120 if (p == NULL) {
121 return;
122 }
123
124 /* Parse and hide the ZEP header */
125 if (p->len < sizeof(struct zep_hdr)) {
126 /* need the zep_hdr in one piece */
127 goto err_return;
128 }
129 zep = (struct zep_hdr *)p->payload;
130 if (zep->prot_id[0] != 'E') {
131 goto err_return;
132 }
133 if (zep->prot_id[1] != 'X') {
134 goto err_return;
135 }
136 if (zep->prot_version != 2) {
137 /* we only support this version for now */
138 goto err_return;
139 }
140 if (zep->type != 1) {
141 goto err_return;
142 }
143 if (zep->crc_mode != 1) {
144 goto err_return;
145 }
146 if (zep->len != p->tot_len - sizeof(struct zep_hdr)) {
147 goto err_return;
148 }
149 /* everything seems to be OK, hide the ZEP header */
150 if (pbuf_remove_header(p, sizeof(struct zep_hdr))) {
151 goto err_return;
152 }
153 /* TODO Check CRC? */
154 /* remove CRC trailer */
155 pbuf_realloc(p, p->tot_len - 2);
156
157 /* Call into 6LoWPAN code. */
158 err = netif_lowpan6->input(p, netif_lowpan6);
159 if (err == ERR_OK) {
160 return;
161 }
162err_return:
163 pbuf_free(p);
164}
165
166/* Send 6LoWPAN TX packets as UDP broadcast */
167static err_t
168zepif_linkoutput(struct netif *netif, struct pbuf *p)
169{
170 err_t err;
171 struct pbuf *q;
172 struct zep_hdr *zep;
173 struct zepif_state *state;
174
175 LWIP_ASSERT("invalid netif", netif != NULL);
176 LWIP_ASSERT("invalid pbuf", p != NULL);
177
178 if (p->tot_len > ZEP_MAX_DATA_LEN) {
179 return ERR_VAL;
180 }
181 LWIP_ASSERT("TODO: support chained pbufs", p->next == NULL);
182
183 state = (struct zepif_state *)netif->state;
184 LWIP_ASSERT("state->pcb != NULL", state->pcb != NULL);
185
186 q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct zep_hdr) + p->tot_len, PBUF_RAM);
187 if (q == NULL) {
188 return ERR_MEM;
189 }
190 zep = (struct zep_hdr *)q->payload;
191 memset(zep, 0, sizeof(struct zep_hdr));
192 zep->prot_id[0] = 'E';
193 zep->prot_id[1] = 'X';
194 zep->prot_version = 2;
195 zep->type = 1; /* Data */
196 zep->channel_id = 0; /* whatever */
197 zep->device_id = lwip_htons(1); /* whatever */
198 zep->crc_mode = 1;
199 zep->unknown_1 = 0xff;
200 zep->seq_num = lwip_htonl(state->seqno);
201 state->seqno++;
202 zep->len = (u8_t)p->tot_len;
203
204 err = pbuf_copy_partial_pbuf(q, p, p->tot_len, sizeof(struct zep_hdr));
205 if (err == ERR_OK) {
206#if ZEPIF_LOOPBACK
207 zepif_udp_recv(netif, state->pcb, pbuf_clone(PBUF_RAW, PBUF_RAM, q), NULL, 0);
208#endif
209 err = udp_sendto(state->pcb, q, state->init.zep_dst_ip_addr, state->init.zep_dst_udp_port);
210 }
211 pbuf_free(q);
212
213 return err;
214}
215
221err_t
222zepif_init(struct netif *netif)
223{
224 err_t err;
225 struct zepif_init *init_state = (struct zepif_init *)netif->state;
226 struct zepif_state *state = (struct zepif_state *)mem_malloc(sizeof(struct zepif_state));
227
228 LWIP_ASSERT("zepif needs an input callback", netif->input != NULL);
229
230 if (state == NULL) {
231 return ERR_MEM;
232 }
233 memset(state, 0, sizeof(struct zepif_state));
234 if (init_state != NULL) {
235 memcpy(&state->init, init_state, sizeof(struct zepif_init));
236 }
237 if (state->init.zep_src_udp_port == 0) {
238 state->init.zep_src_udp_port = ZEPIF_DEFAULT_UDP_PORT;
239 }
240 if (state->init.zep_dst_udp_port == 0) {
241 state->init.zep_dst_udp_port = ZEPIF_DEFAULT_UDP_PORT;
242 }
243#if LWIP_IPV4
244 if (state->init.zep_dst_ip_addr == NULL) {
245 /* With IPv4 enabled, default to broadcasting packets if no address is set */
246 state->init.zep_dst_ip_addr = IP_ADDR_BROADCAST;
247 }
248#endif /* LWIP_IPV4 */
249
250 netif->state = NULL;
251
252 state->pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
253 if (state->pcb == NULL) {
254 err = ERR_MEM;
255 goto err_ret;
256 }
257 err = udp_bind(state->pcb, state->init.zep_src_ip_addr, state->init.zep_src_udp_port);
258 if (err != ERR_OK) {
259 goto err_ret;
260 }
261 if (state->init.zep_netif != NULL) {
262 udp_bind_netif(state->pcb, state->init.zep_netif);
263 }
264 LWIP_ASSERT("udp_bind(lowpan6_broadcast_pcb) failed", err == ERR_OK);
266 udp_recv(state->pcb, zepif_udp_recv, netif);
267
268 err = lowpan6_if_init(netif);
269 LWIP_ASSERT("lowpan6_if_init set a state", netif->state == NULL);
270 if (err == ERR_OK) {
271 netif->state = state;
272 netif->hwaddr_len = 6;
273 if (init_state != NULL) {
274 memcpy(netif->hwaddr, init_state->addr, 6);
275 } else {
276 u8_t i;
277 for (i = 0; i < 6; i++) {
278 netif->hwaddr[i] = i;
279 }
280 netif->hwaddr[0] &= 0xfc;
281 }
282 netif->linkoutput = zepif_linkoutput;
283
284 if (!zep_lowpan_timer_running) {
285 sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, NULL);
286 zep_lowpan_timer_running = 1;
287 }
288
289 return ERR_OK;
290 }
291
292err_ret:
293 if (state->pcb != NULL) {
294 udp_remove(state->pcb);
295 }
297 return err;
298}
299
300#endif /* LWIP_IPV6 && LWIP_UDP */
static int state
Definition: maze.c:121
#define lwip_htons(x)
Definition: def.h:86
#define lwip_htonl(x)
Definition: def.h:88
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
USHORT port
Definition: uri.c:228
#define PACK_STRUCT_STRUCT
Definition: cc.h:42
void * mem_malloc(mem_size_t size_in)
Definition: mem.c:831
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
#define ip_set_option(pcb, opt)
Definition: ip.h:230
#define SOF_BROADCAST
Definition: ip.h:112
#define ERR_MEM
Definition: fontsub.h:52
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define PACK_STRUCT_END
Definition: arch.h:316
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
#define PACK_STRUCT_BEGIN
Definition: arch.h:307
uint16_t u16_t
Definition: arch.h:127
#define PACK_STRUCT_FLD_8(x)
Definition: arch.h:347
#define PACK_STRUCT_FIELD(x)
Definition: arch.h:338
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
@ ERR_VAL
Definition: err.h:67
@ IPADDR_TYPE_ANY
Definition: ip_addr.h:60
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:402
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
struct pbuf * pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p)
Definition: pbuf.c:1337
err_t pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset)
Definition: pbuf.c:986
@ PBUF_RAM
Definition: pbuf.h:152
@ PBUF_RAW
Definition: pbuf.h:111
@ PBUF_TRANSPORT
Definition: pbuf.h:93
ip6_addr_t ip_addr_t
Definition: ip_addr.h:344
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
u8_t pbuf_remove_header(struct pbuf *p, size_t header_size_decrement)
Definition: pbuf.c:585
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
Definition: netif.h:269
void * state
Definition: netif.h:332
netif_input_fn input
Definition: netif.h:297
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:350
netif_linkoutput_fn linkoutput
Definition: netif.h:308
u8_t hwaddr_len
Definition: netif.h:352
Definition: pbuf.h:186
static int init
Definition: wintirpc.c:33