Removing IPv4 stack
This commit is contained in:
parent
d61cb46e59
commit
1a0f8ab737
@ -66,11 +66,6 @@ MODULES += core/sys core/dev core/lib
|
||||
# Include IPv6, IPv4, and/or Rime
|
||||
|
||||
HAS_STACK = 0
|
||||
ifeq ($(CONTIKI_WITH_IPV4),1)
|
||||
HAS_STACK = 1
|
||||
CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1
|
||||
MODULES += core/net/ipv4 core/net/ip
|
||||
endif
|
||||
|
||||
# Make IPv6 the default stack
|
||||
ifeq ($(HAS_STACK),0)
|
||||
|
@ -67,11 +67,7 @@
|
||||
|
||||
/* direct access into the buffer */
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#else
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#endif
|
||||
|
||||
/* bitmap for set options */
|
||||
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
|
||||
|
@ -158,14 +158,6 @@
|
||||
#define UIP_CONF_MAX_CONNECTIONS 8
|
||||
#endif /* UIP_CONF_MAX_CONNECTIONS */
|
||||
|
||||
|
||||
/* UIP_CONF_TCP_SPLIT enables a performance optimization hack, where
|
||||
each maximum-sized TCP segment is split into two, to avoid the
|
||||
performance degradation that is caused by delayed ACKs. */
|
||||
#ifndef UIP_CONF_TCP_SPLIT
|
||||
#define UIP_CONF_TCP_SPLIT 0
|
||||
#endif /* UIP_CONF_TCP_SPLIT */
|
||||
|
||||
/* NBR_TABLE_CONF_MAX_NEIGHBORS specifies the maximum number of neighbors
|
||||
that each node will be able to handle. */
|
||||
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
|
||||
|
@ -38,9 +38,6 @@
|
||||
|
||||
#include "net/ip/tcpip.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#include "net/ipv4/uip-fw-drv.h"
|
||||
#include "net/ipv4/uip_arp.h"
|
||||
#include "net/ip/uiplib.h"
|
||||
#include "net/ip/uip-udp-packet.h"
|
||||
#include "net/ip/simple-udp.h"
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "contiki.h"
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
@ -334,41 +333,7 @@ PROCESS_THREAD(slip_process, ev, data)
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) {
|
||||
char buf[8];
|
||||
memcpy(&buf[0], "=IPA", 4);
|
||||
memcpy(&buf[4], &uip_hostaddr, 4);
|
||||
if(input_callback) {
|
||||
input_callback();
|
||||
}
|
||||
slip_write(buf, 8);
|
||||
} else if(uip_len > 0
|
||||
&& uip_len == (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1])
|
||||
&& uip_ipchksum() == 0xffff) {
|
||||
#define IP_DF 0x40
|
||||
if(BUF->ipid[0] == 0 && BUF->ipid[1] == 0 && BUF->ipoffset[0] & IP_DF) {
|
||||
static uint16_t ip_id;
|
||||
uint16_t nid = ip_id++;
|
||||
BUF->ipid[0] = nid >> 8;
|
||||
BUF->ipid[1] = nid;
|
||||
nid = uip_htons(nid);
|
||||
nid = ~nid; /* negate */
|
||||
BUF->ipchksum += nid; /* add */
|
||||
if(BUF->ipchksum < nid) { /* 1-complement overflow? */
|
||||
BUF->ipchksum++;
|
||||
}
|
||||
}
|
||||
#ifdef SLIP_CONF_TCPIP_INPUT
|
||||
SLIP_CONF_TCPIP_INPUT();
|
||||
#else
|
||||
tcpip_input();
|
||||
#endif
|
||||
} else {
|
||||
uip_clear_buf();
|
||||
SLIP_STATISTICS(slip_ip_drop++);
|
||||
}
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
if(uip_len > 0) {
|
||||
if(input_callback) {
|
||||
input_callback();
|
||||
@ -379,7 +344,6 @@ PROCESS_THREAD(slip_process, ev, data)
|
||||
tcpip_input();
|
||||
#endif
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
|
@ -189,11 +189,7 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#define DNS_TYPE_ANY 255
|
||||
#define DNS_TYPE_NSEC 47
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define NATIVE_DNS_TYPE DNS_TYPE_AAAA /* IPv6 */
|
||||
#else
|
||||
#define NATIVE_DNS_TYPE DNS_TYPE_A /* IPv4 */
|
||||
#endif
|
||||
|
||||
#define DNS_CLASS_IN 1
|
||||
#define DNS_CLASS_ANY 255
|
||||
@ -239,11 +235,7 @@ struct dns_answer {
|
||||
uint16_t class;
|
||||
uint16_t ttl[2];
|
||||
uint16_t len;
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uint8_t ipaddr[16];
|
||||
#else
|
||||
uint8_t ipaddr[4];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct namemap {
|
||||
@ -307,13 +299,10 @@ enum {
|
||||
static uint8_t mdns_state;
|
||||
|
||||
static const uip_ipaddr_t resolv_mdns_addr =
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
{ { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } };
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
{ { 224, 0, 0, 251 } };
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
static int mdns_needs_host_announce;
|
||||
|
||||
PROCESS(mdns_probe_process, "mDNS probe");
|
||||
@ -498,7 +487,6 @@ start_name_collision_check(clock_time_t after)
|
||||
static unsigned char *
|
||||
mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
||||
{
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uint8_t i;
|
||||
|
||||
for(i = 0; i < UIP_DS6_ADDR_NB; ++i) {
|
||||
@ -534,20 +522,6 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
||||
++(*count);
|
||||
}
|
||||
}
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
struct dns_answer *ans;
|
||||
|
||||
queryptr = encode_name(queryptr, resolv_hostname);
|
||||
ans = (struct dns_answer *)queryptr;
|
||||
ans->type = UIP_HTONS(NATIVE_DNS_TYPE);
|
||||
ans->class = UIP_HTONS(DNS_CLASS_IN | 0x8000);
|
||||
ans->ttl[0] = 0;
|
||||
ans->ttl[1] = UIP_HTONS(120);
|
||||
ans->len = UIP_HTONS(sizeof(uip_ipaddr_t));
|
||||
uip_gethostaddr((uip_ipaddr_t *) ans->ipaddr);
|
||||
queryptr = (unsigned char *)ans + sizeof(*ans);
|
||||
++(*count);
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
return queryptr;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -576,17 +550,10 @@ mdns_prep_host_announce_packet(void)
|
||||
0x00,
|
||||
0x04,
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x08,
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
};
|
||||
|
||||
@ -1173,11 +1140,7 @@ PROCESS_THREAD(resolv_process, ev, data)
|
||||
PRINTF("resolver: Supports MDNS.\n");
|
||||
uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT));
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uip_ds6_maddr_add(&resolv_mdns_addr);
|
||||
#else
|
||||
/* TODO: Is there anything we need to do here for IPv4 multicast? */
|
||||
#endif
|
||||
|
||||
resolv_set_hostname(CONTIKI_CONF_DEFAULT_HOSTNAME);
|
||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||
@ -1360,12 +1323,8 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr)
|
||||
#if UIP_CONF_LOOPBACK_INTERFACE
|
||||
if(strcmp(name, "localhost")) {
|
||||
static uip_ipaddr_t loopback =
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } };
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
{ { 127, 0, 0, 1 } };
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(ipaddr) {
|
||||
*ipaddr = &loopback;
|
||||
}
|
||||
@ -1448,11 +1407,7 @@ resolv_found(char *name, uip_ipaddr_t * ipaddr)
|
||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||
if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
|
||||
ipaddr
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
&& !uip_ds6_is_my_addr(ipaddr)
|
||||
#else
|
||||
&& uip_ipaddr_cmp(&uip_hostaddr, ipaddr) != 0
|
||||
#endif
|
||||
) {
|
||||
uint8_t i;
|
||||
|
||||
|
@ -39,13 +39,10 @@
|
||||
*/
|
||||
|
||||
#include "contiki-net.h"
|
||||
#include "net/ip/uip-split.h"
|
||||
#include "net/ip/uip-packetqueue.h"
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#include "net/ipv6/uip-nd6.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
#include "net/rpl/rpl.h"
|
||||
@ -85,7 +82,7 @@ process_event_t tcpip_icmp6_event;
|
||||
/* Periodic check of active connections. */
|
||||
static struct etimer periodic;
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
/* Timer for reassembly. */
|
||||
extern struct etimer uip_reass_timer;
|
||||
#endif
|
||||
@ -111,8 +108,7 @@ enum {
|
||||
PACKET_INPUT
|
||||
};
|
||||
|
||||
/* Called on IP packet output. */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
|
||||
|
||||
static uint8_t (* outputfunc)(const uip_lladdr_t *a);
|
||||
|
||||
@ -133,34 +129,11 @@ tcpip_set_outputfunc(uint8_t (*f)(const uip_lladdr_t *))
|
||||
{
|
||||
outputfunc = f;
|
||||
}
|
||||
#else
|
||||
|
||||
static uint8_t (* outputfunc)(void);
|
||||
uint8_t
|
||||
tcpip_output(void)
|
||||
{
|
||||
if(outputfunc != NULL) {
|
||||
return outputfunc();
|
||||
}
|
||||
UIP_LOG("tcpip_output: Use tcpip_set_outputfunc() to set an output function");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
tcpip_set_outputfunc(uint8_t (*f)(void))
|
||||
{
|
||||
outputfunc = f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_IP_FORWARD
|
||||
unsigned char tcpip_is_forwarding; /* Forwarding right now? */
|
||||
#endif /* UIP_CONF_IP_FORWARD */
|
||||
|
||||
PROCESS(tcpip_process, "TCP/IP stack");
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UIP_TCP || UIP_CONF_IP_FORWARD
|
||||
#if UIP_TCP
|
||||
static void
|
||||
start_periodic_tcp_timer(void)
|
||||
{
|
||||
@ -168,12 +141,12 @@ start_periodic_tcp_timer(void)
|
||||
etimer_restart(&periodic);
|
||||
}
|
||||
}
|
||||
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
|
||||
#endif /* UIP_TCP */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
check_for_tcp_syn(void)
|
||||
{
|
||||
#if UIP_TCP || UIP_CONF_IP_FORWARD
|
||||
#if UIP_TCP
|
||||
/* This is a hack that is needed to start the periodic TCP timer if
|
||||
an incoming packet contains a SYN: since uIP does not inform the
|
||||
application if a SYN arrives, we have no other way of starting
|
||||
@ -184,36 +157,17 @@ check_for_tcp_syn(void)
|
||||
(UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
|
||||
start_periodic_tcp_timer();
|
||||
}
|
||||
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
|
||||
#endif /* UIP_TCP */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
packet_input(void)
|
||||
{
|
||||
if(uip_len > 0) {
|
||||
|
||||
#if UIP_CONF_IP_FORWARD
|
||||
tcpip_is_forwarding = 1;
|
||||
if(uip_fw_forward() != UIP_FW_LOCAL) {
|
||||
tcpip_is_forwarding = 0;
|
||||
return;
|
||||
}
|
||||
tcpip_is_forwarding = 0;
|
||||
#endif /* UIP_CONF_IP_FORWARD */
|
||||
|
||||
check_for_tcp_syn();
|
||||
uip_input();
|
||||
if(uip_len > 0) {
|
||||
#if UIP_CONF_TCP_SPLIT
|
||||
uip_split_output();
|
||||
#else /* UIP_CONF_TCP_SPLIT */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
PRINTF("tcpip packet_input output len %d\n", uip_len);
|
||||
tcpip_output();
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#endif /* UIP_CONF_TCP_SPLIT */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,11 +278,8 @@ udp_broadcast_new(uint16_t port, void *appstate)
|
||||
uip_ipaddr_t addr;
|
||||
struct uip_udp_conn *conn;
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uip_create_linklocal_allnodes_mcast(&addr);
|
||||
#else
|
||||
uip_ipaddr(&addr, 255,255,255,255);
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
conn = udp_new(&addr, port, appstate);
|
||||
if(conn != NULL) {
|
||||
udp_bind(conn, port);
|
||||
@ -427,24 +378,12 @@ eventhandler(process_event_t ev, process_data_t data)
|
||||
connections. */
|
||||
etimer_restart(&periodic);
|
||||
uip_periodic(i);
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else
|
||||
if(uip_len > 0) {
|
||||
PRINTF("tcpip_output from periodic len %d\n", uip_len);
|
||||
tcpip_output();
|
||||
PRINTF("tcpip_output after periodic len %d\n", uip_len);
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
#if UIP_CONF_IP_FORWARD
|
||||
uip_fw_periodic();
|
||||
#endif /* UIP_CONF_IP_FORWARD */
|
||||
}
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
/*
|
||||
* check the timer for reassembly
|
||||
@ -476,7 +415,6 @@ eventhandler(process_event_t ev, process_data_t data)
|
||||
uip_ds6_periodic();
|
||||
tcpip_ipv6_output();
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
break;
|
||||
|
||||
@ -484,14 +422,7 @@ eventhandler(process_event_t ev, process_data_t data)
|
||||
case TCP_POLL:
|
||||
if(data != NULL) {
|
||||
uip_poll_conn(data);
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(uip_len > 0) {
|
||||
PRINTF("tcpip_output from tcp poll len %d\n", uip_len);
|
||||
tcpip_output();
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* Start the periodic polling, if it isn't already active. */
|
||||
start_periodic_tcp_timer();
|
||||
}
|
||||
@ -501,13 +432,7 @@ eventhandler(process_event_t ev, process_data_t data)
|
||||
case UDP_POLL:
|
||||
if(data != NULL) {
|
||||
uip_udp_periodic_conn(data);
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else
|
||||
if(uip_len > 0) {
|
||||
tcpip_output();
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
}
|
||||
break;
|
||||
#endif /* UIP_UDP */
|
||||
@ -525,7 +450,6 @@ tcpip_input(void)
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
void
|
||||
tcpip_ipv6_output(void)
|
||||
{
|
||||
@ -746,7 +670,6 @@ tcpip_ipv6_output(void)
|
||||
tcpip_output(NULL);
|
||||
uip_clear_buf();
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UIP_UDP
|
||||
void
|
||||
@ -835,7 +758,7 @@ PROCESS_THREAD(tcpip_process, ev, data)
|
||||
UIP_FALLBACK_INTERFACE.init();
|
||||
#endif
|
||||
/* initialize RPL if configured for using RPL */
|
||||
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
rpl_init();
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
||||
|
@ -340,20 +340,13 @@ CCIF void tcpip_input(void);
|
||||
* \brief Output packet to layer 2
|
||||
* The eventual parameter is the MAC address of the destination.
|
||||
*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uint8_t tcpip_output(const uip_lladdr_t *);
|
||||
void tcpip_set_outputfunc(uint8_t (* f)(const uip_lladdr_t *));
|
||||
#else
|
||||
uint8_t tcpip_output(void);
|
||||
void tcpip_set_outputfunc(uint8_t (* f)(void));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief This function does address resolution and then calls tcpip_output
|
||||
*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
void tcpip_ipv6_output(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Is forwarding generally enabled?
|
||||
|
@ -44,16 +44,15 @@
|
||||
void
|
||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
||||
{
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uint16_t a;
|
||||
unsigned int i;
|
||||
int f;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
if(addr == NULL) {
|
||||
PRINTA("(NULL IP addr)");
|
||||
return;
|
||||
}
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
|
||||
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
|
||||
/*
|
||||
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
|
||||
@ -87,8 +86,5 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "net/ip/uip-split.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#include "net/ip/uip_arch.h"
|
||||
|
||||
#include "net/ip/tcpip.h"
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#ifdef UIP_SPLIT_CONF_SIZE
|
||||
#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE
|
||||
#else /* UIP_SPLIT_CONF_SIZE */
|
||||
#define UIP_SPLIT_SIZE UIP_TCP_MSS
|
||||
#endif /* UIP_SPLIT_CONF_SIZE */
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_split_output(void)
|
||||
{
|
||||
#if UIP_TCP
|
||||
uint16_t tcplen, len1, len2;
|
||||
|
||||
/* We only split TCP segments that are larger than or equal to
|
||||
UIP_SPLIT_SIZE, which is configurable through
|
||||
UIP_SPLIT_CONF_SIZE. */
|
||||
if(BUF->proto == UIP_PROTO_TCP &&
|
||||
uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {
|
||||
|
||||
tcplen = uip_len - UIP_TCPIP_HLEN;
|
||||
/* Split the segment in two. If the original packet length was
|
||||
odd, we make the second packet one byte larger. */
|
||||
len1 = len2 = tcplen / 2;
|
||||
if(len1 + len2 < tcplen) {
|
||||
++len2;
|
||||
}
|
||||
|
||||
/* Create the first packet. This is done by altering the length
|
||||
field of the IP header and updating the checksums. */
|
||||
uip_len = len1 + UIP_TCPIP_HLEN;
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
BUF->len[0] = uip_len >> 8;
|
||||
BUF->len[1] = uip_len & 0xff;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* Recalculate the TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
/* Recalculate the IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* Transmit the first packet. */
|
||||
/* uip_fw_output();*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else
|
||||
tcpip_output();
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* Now, create the second packet. To do this, it is not enough to
|
||||
just alter the length field, but we must also update the TCP
|
||||
sequence number and point the uip_appdata to a new place in
|
||||
memory. This place is detemined by the length of the first
|
||||
packet (len1). */
|
||||
uip_len = len2 + UIP_TCPIP_HLEN;
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
BUF->len[0] = uip_len >> 8;
|
||||
BUF->len[1] = uip_len & 0xff;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* uip_appdata += len1;*/
|
||||
memcpy(uip_appdata, (uint8_t *)uip_appdata + len1, len2);
|
||||
|
||||
uip_add32(BUF->seqno, len1);
|
||||
BUF->seqno[0] = uip_acc32[0];
|
||||
BUF->seqno[1] = uip_acc32[1];
|
||||
BUF->seqno[2] = uip_acc32[2];
|
||||
BUF->seqno[3] = uip_acc32[3];
|
||||
|
||||
/* Recalculate the TCP checksum. */
|
||||
BUF->tcpchksum = 0;
|
||||
BUF->tcpchksum = ~(uip_tcpchksum());
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
/* Recalculate the IP checksum. */
|
||||
BUF->ipchksum = 0;
|
||||
BUF->ipchksum = ~(uip_ipchksum());
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* Transmit the second packet. */
|
||||
/* uip_fw_output();*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else
|
||||
tcpip_output();
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
return;
|
||||
}
|
||||
#endif /* UIP_TCP */
|
||||
|
||||
/* uip_fw_output();*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
tcpip_ipv6_output();
|
||||
#else
|
||||
tcpip_output();
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \addtogroup uip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup uipsplit uIP TCP throughput booster hack
|
||||
* @{
|
||||
*
|
||||
* The basic uIP TCP implementation only allows each TCP connection to
|
||||
* have a single TCP segment in flight at any given time. Because of
|
||||
* the delayed ACK algorithm employed by most TCP receivers, uIP's
|
||||
* limit on the amount of in-flight TCP segments seriously reduces the
|
||||
* maximum achievable throughput for sending data from uIP.
|
||||
*
|
||||
* The uip-split module is a hack which tries to remedy this
|
||||
* situation. By splitting maximum sized outgoing TCP segments into
|
||||
* two, the delayed ACK algorithm is not invoked at TCP
|
||||
* receivers. This improves the throughput when sending data from uIP
|
||||
* by orders of magnitude.
|
||||
*
|
||||
* The uip-split module uses the uip-fw module (uIP IP packet
|
||||
* forwarding) for sending packets. Therefore, the uip-fw module must
|
||||
* be set up with the appropriate network interfaces for this module
|
||||
* to work.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Module for splitting outbound TCP segments in two to avoid the
|
||||
* delayed ACK throughput degradation.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UIP_SPLIT_H_
|
||||
#define UIP_SPLIT_H_
|
||||
|
||||
/**
|
||||
* Handle outgoing packets.
|
||||
*
|
||||
* This function inspects an outgoing packet in the uip_buf buffer and
|
||||
* sends it out using the uip_fw_output() function. If the packet is a
|
||||
* full-sized TCP segment it will be split into two segments and
|
||||
* transmitted separately. This function should be called instead of
|
||||
* the actual device driver output function, or the uip_fw_output()
|
||||
* function.
|
||||
*
|
||||
* The headers of the outgoing packet is assumed to be in the uip_buf
|
||||
* buffer and the payload is assumed to be wherever uip_appdata
|
||||
* points. The length of the outgoing packet is assumed to be in the
|
||||
* uip_len variable.
|
||||
*
|
||||
*/
|
||||
void uip_split_output(void);
|
||||
|
||||
#endif /* UIP_SPLIT_H_ */
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
@ -53,12 +53,8 @@
|
||||
#define UIP_H_
|
||||
|
||||
/* Header sizes. */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define UIP_IPH_LEN 40
|
||||
#define UIP_FRAGH_LEN 8
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#define UIP_IPH_LEN 20 /* Size of IP header */
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#define UIP_UDPH_LEN 8 /* Size of UDP header */
|
||||
#define UIP_TCPH_LEN 20 /* Size of TCP header */
|
||||
@ -1501,7 +1497,18 @@ struct uip_stats {
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The Ethernet header.
|
||||
*/
|
||||
struct uip_eth_hdr {
|
||||
struct uip_eth_addr dest;
|
||||
struct uip_eth_addr src;
|
||||
uint16_t type;
|
||||
};
|
||||
|
||||
#define UIP_ETHTYPE_ARP 0x0806
|
||||
#define UIP_ETHTYPE_IP 0x0800
|
||||
#define UIP_ETHTYPE_IPV6 0x86dd
|
||||
|
||||
/* uint8_t uip_flags:
|
||||
*
|
||||
@ -2154,6 +2161,60 @@ CCIF extern uip_lladdr_t uip_lladdr;
|
||||
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet should be
|
||||
* processed locally.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_LOCAL 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that something went OK.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_OK 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet was forwarded.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_FORWARDED 1
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a zero-length packet
|
||||
* transmission was attempted, and that no packet was sent.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_ZEROLEN 2
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that was too large
|
||||
* for the outbound network interface was detected.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_TOOLARGE 3
|
||||
|
||||
/**
|
||||
* An error message that indicates that no suitable interface could be
|
||||
* found for an outbound packet.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_NOROUTE 4
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that should be
|
||||
* forwarded or output was dropped.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_DROPPED 5
|
||||
|
||||
/**
|
||||
* Calculate the Internet checksum over a buffer.
|
||||
*
|
||||
|
@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Definitions for the micro implementation of the AODV ad hoc routing protocol
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef UAODV_DEF_H_
|
||||
#define UAODV_DEF_H_
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
|
||||
#define NUM_PRECURSORS 4
|
||||
|
||||
|
||||
#define UAODV_UDPPORT 654
|
||||
|
||||
#if 0
|
||||
/* AODV routing table entry */
|
||||
struct uaodv_rtentry {
|
||||
uip_ipaddr_t dest_addr;
|
||||
uip_ipaddr_t next_hop;
|
||||
uip_ipaddr_t precursors[NUM_PRECURSORS];
|
||||
uint32_t dest_seqno;
|
||||
uint16_t lifetime;
|
||||
uint8_t dest_seqno_flag;
|
||||
uint8_t route_flags;
|
||||
uint8_t hop_count;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Generic AODV message */
|
||||
struct uaodv_msg {
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
/* AODV RREQ message */
|
||||
#define UAODV_RREQ_TYPE 1
|
||||
#define UAODV_RREQ_JOIN (1 << 7)
|
||||
#define UAODV_RREQ_REPAIR (1 << 6)
|
||||
#define UAODV_RREQ_GRATIOUS (1 << 5)
|
||||
#define UAODV_RREQ_DESTONLY (1 << 4)
|
||||
#define UAODV_RREQ_UNKSEQNO (1 << 3)
|
||||
|
||||
struct uaodv_msg_rreq {
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
uint8_t reserved;
|
||||
uint8_t hop_count;
|
||||
uint32_t rreq_id;
|
||||
uip_ipaddr_t dest_addr;
|
||||
uint32_t dest_seqno;
|
||||
uip_ipaddr_t orig_addr;
|
||||
uint32_t orig_seqno;
|
||||
};
|
||||
|
||||
/* AODV RREP message */
|
||||
#define UAODV_RREP_TYPE 2
|
||||
#define UAODV_RREP_REPAIR (1 << 7)
|
||||
#define UAODV_RREP_ACK (1 << 6)
|
||||
|
||||
struct uaodv_msg_rrep {
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
uint8_t prefix_sz; /* prefix_sz:5 */
|
||||
uint8_t hop_count;
|
||||
uip_ipaddr_t dest_addr;
|
||||
uint32_t dest_seqno;
|
||||
uip_ipaddr_t orig_addr;
|
||||
uint32_t lifetime;
|
||||
};
|
||||
|
||||
/* AODV RERR message */
|
||||
#define UAODV_RERR_TYPE 3
|
||||
#define UAODV_RERR_NODELETE (1 << 7)
|
||||
#define UAODV_RERR_UNKNOWN (1 << 6) /* Non standard extension /bg. */
|
||||
|
||||
struct uaodv_msg_rerr {
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
uint8_t reserved;
|
||||
uint8_t dest_count;
|
||||
struct {
|
||||
uip_ipaddr_t addr;
|
||||
uint32_t seqno;
|
||||
} unreach[1];
|
||||
};
|
||||
|
||||
/* AODV RREP-ACK message */
|
||||
#define UAODV_RREP_ACK_TYPE 4
|
||||
|
||||
struct uaodv_msg_rrep_ack {
|
||||
uint8_t type;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
#define RREP_HELLO_INTERVAL_EXT 1 /* Per RFC 3561. */
|
||||
#define RREQ_BAD_HOP_EXT 101 /* Non standard extension /bg */
|
||||
|
||||
struct uaodv_extension {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
/* uint8_t value[length]; */
|
||||
};
|
||||
|
||||
struct uaodv_bad_hop_ext {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t unused1, unused2;
|
||||
uip_ipaddr_t addrs[1];
|
||||
};
|
||||
|
||||
#endif /* UAODV_DEF_H_ */
|
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Routing tables for the micro implementation of the AODV ad hoc routing protocol
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
|
||||
#include "net/ipv4/uaodv-rt.h"
|
||||
#include "contiki-net.h"
|
||||
|
||||
#ifndef UAODV_NUM_RT_ENTRIES
|
||||
#define UAODV_NUM_RT_ENTRIES 8
|
||||
#endif
|
||||
|
||||
/*
|
||||
* LRU (with respect to insertion time) list of route entries.
|
||||
*/
|
||||
LIST(route_table);
|
||||
MEMB(route_mem, struct uaodv_rt_entry, UAODV_NUM_RT_ENTRIES);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uaodv_rt_init(void)
|
||||
{
|
||||
list_init(route_table);
|
||||
memb_init(&route_mem);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct uaodv_rt_entry *
|
||||
uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop,
|
||||
unsigned hop_count, const uint32_t *seqno)
|
||||
{
|
||||
struct uaodv_rt_entry *e;
|
||||
|
||||
/* Avoid inserting duplicate entries. */
|
||||
e = uaodv_rt_lookup_any(dest);
|
||||
if(e != NULL) {
|
||||
list_remove(route_table, e);
|
||||
} else {
|
||||
/* Allocate a new entry or reuse the oldest. */
|
||||
e = memb_alloc(&route_mem);
|
||||
if(e == NULL) {
|
||||
e = list_chop(route_table); /* Remove oldest entry. */
|
||||
}
|
||||
}
|
||||
|
||||
uip_ipaddr_copy(&e->dest, dest);
|
||||
uip_ipaddr_copy(&e->nexthop, nexthop);
|
||||
e->hop_count = hop_count;
|
||||
e->hseqno = uip_ntohl(*seqno);
|
||||
e->is_bad = 0;
|
||||
|
||||
/* New entry goes first. */
|
||||
list_push(route_table, e);
|
||||
|
||||
return e;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct uaodv_rt_entry *
|
||||
uaodv_rt_lookup_any(uip_ipaddr_t *dest)
|
||||
{
|
||||
struct uaodv_rt_entry *e;
|
||||
|
||||
for(e = list_head(route_table); e != NULL; e = e->next) {
|
||||
if(uip_ipaddr_cmp(dest, &e->dest)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct uaodv_rt_entry *
|
||||
uaodv_rt_lookup(uip_ipaddr_t *dest)
|
||||
{
|
||||
struct uaodv_rt_entry *e;
|
||||
|
||||
e = uaodv_rt_lookup_any(dest);
|
||||
if(e != NULL && e->is_bad)
|
||||
return NULL;
|
||||
return e;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
void
|
||||
uaodv_rt_remove(struct uaodv_rt_entry *e)
|
||||
{
|
||||
list_remove(route_table, e);
|
||||
memb_free(&route_mem, e);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
uaodv_rt_lru(struct uaodv_rt_entry *e)
|
||||
{
|
||||
if(e != list_head(route_table)) {
|
||||
list_remove(route_table, e);
|
||||
list_push(route_table, e);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uaodv_rt_flush_all(void)
|
||||
{
|
||||
struct uaodv_rt_entry *e;
|
||||
|
||||
while (1) {
|
||||
e = list_pop(route_table);
|
||||
if(e != NULL)
|
||||
memb_free(&route_mem, e);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Routing tables for the micro implementation of the AODV ad hoc routing protocol
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef UAODV_RT_H_
|
||||
#define UAODV_RT_H_
|
||||
|
||||
#include "contiki-net.h"
|
||||
|
||||
struct uaodv_rt_entry {
|
||||
struct uaodv_rt_entry *next;
|
||||
uip_ipaddr_t dest;
|
||||
uip_ipaddr_t nexthop;
|
||||
uint32_t hseqno; /* In host byte order! */
|
||||
uint8_t hop_count;
|
||||
uint8_t is_bad; /* Only one bit is used. */
|
||||
};
|
||||
|
||||
struct uaodv_rt_entry *
|
||||
uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop,
|
||||
unsigned hop_count, const uint32_t *seqno);
|
||||
struct uaodv_rt_entry *uaodv_rt_lookup_any(uip_ipaddr_t *dest);
|
||||
struct uaodv_rt_entry *uaodv_rt_lookup(uip_ipaddr_t *dest);
|
||||
void uaodv_rt_remove(struct uaodv_rt_entry *e);
|
||||
void uaodv_rt_lru(struct uaodv_rt_entry *e);
|
||||
void uaodv_rt_flush_all(void);
|
||||
|
||||
#endif /* UAODV_RT_H_ */
|
@ -1,616 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Micro implementation of the AODV ad hoc routing protocol
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/ipv4/uaodv-def.h"
|
||||
#include "net/ipv4/uaodv-rt.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include "lib/assert.h"
|
||||
|
||||
#ifdef CC2420_RADIO
|
||||
#include "cc2420.h"
|
||||
#define RSSI_THRESHOLD -39 /* accept -39 ... xx */
|
||||
#endif
|
||||
|
||||
/* This implementation never expires routes!!! */
|
||||
#define MY_ROUTE_TIMEOUT 0x7fffffff /* Should be 0xffffffff! */
|
||||
#define MY_NET_DIAMETER 20
|
||||
|
||||
PROCESS(uaodv_process, "uAODV");
|
||||
|
||||
static struct uip_udp_conn *bcastconn, *unicastconn;
|
||||
|
||||
/* Compare sequence numbers as per RFC 3561. */
|
||||
#define SCMP32(a, b) ((int32_t)((a) - (b)))
|
||||
|
||||
static CC_INLINE uint32_t
|
||||
last_known_seqno(uip_ipaddr_t *host)
|
||||
{
|
||||
struct uaodv_rt_entry *route = uaodv_rt_lookup_any(host);
|
||||
|
||||
if(route != NULL)
|
||||
return uip_htonl(route->hseqno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t rreq_id, my_hseqno; /* In host byte order! */
|
||||
|
||||
#define NFWCACHE 16
|
||||
|
||||
static struct {
|
||||
uip_ipaddr_t orig;
|
||||
uint32_t id;
|
||||
} fwcache[NFWCACHE];
|
||||
|
||||
static CC_INLINE int
|
||||
fwc_lookup(const uip_ipaddr_t *orig, const uint32_t *id)
|
||||
{
|
||||
unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
|
||||
return fwcache[n].id == *id && uip_ipaddr_cmp(&fwcache[n].orig, orig);
|
||||
}
|
||||
|
||||
static CC_INLINE void
|
||||
fwc_add(const uip_ipaddr_t *orig, const uint32_t *id)
|
||||
{
|
||||
unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
|
||||
fwcache[n].id = *id;
|
||||
uip_ipaddr_copy(&fwcache[n].orig, orig);
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define PRINTF(...) do {} while (0)
|
||||
#define print_debug(...) do{}while(0)
|
||||
#else
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#ifdef __GNUC__
|
||||
static void
|
||||
print_debug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
#endif /* __GNUC__ */
|
||||
static void
|
||||
print_debug(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
printf("%d.%d.%d.%d: ", uip_ipaddr_to_quad(&uip_hostaddr));
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define uip_udp_sender() (&BUF->srcipaddr)
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
sendto(const uip_ipaddr_t *dest, const void *buf, int len)
|
||||
{
|
||||
/* XXX: this is a HACK! We're updating the uIP UDP connection
|
||||
"unicastconn" so that the destination address is the next-hop,
|
||||
and we're patching the "uip_udp_conn" variable so that it points
|
||||
the this connection instead. THIS IS NOT A NICE WAY TO DO THIS,
|
||||
but it is currently nicer than the alternative (requesting a new
|
||||
poll, and remembering the state, etc.). */
|
||||
|
||||
uip_ipaddr_copy(&unicastconn->ripaddr, dest);
|
||||
uip_udp_conn = unicastconn;
|
||||
uip_udp_packet_send(unicastconn, buf, len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef AODV_BAD_HOP_EXTENSION
|
||||
static unsigned
|
||||
add_rreq_extensions(void *_p)
|
||||
{
|
||||
struct uaodv_bad_hop_ext *p = _p;
|
||||
uip_ipaddr_t *a = p->addrs;
|
||||
unsigned i, n;
|
||||
|
||||
#define SCALE_RETRANS_THRESHOLD (3*4)
|
||||
|
||||
cc2420_check_remote(0xffff); /* Age table. */
|
||||
n = 0;
|
||||
for (i = 0; i < NNEIGBOURS; i++) {
|
||||
if (neigbours[i].nretrans >= SCALE_RETRANS_THRESHOLD
|
||||
&& neigbours[i].mac != 0xffff) {
|
||||
a->u16[0] = uip_hostaddr.u16[0];
|
||||
a->u16[1] = neigbours[i].mac;
|
||||
n++;
|
||||
if(n == 15)
|
||||
break; /* Avoid buffer overrun */
|
||||
print_debug("BAD HOP %d.%d.%d.%d\t%d\n",
|
||||
uip_ipaddr_to_quad(a), neigbours[i].nretrans);
|
||||
}
|
||||
}
|
||||
|
||||
if(n == 0)
|
||||
return 0;
|
||||
|
||||
p->type = RREQ_BAD_HOP_EXT;
|
||||
p->length = 2 + 4*n; /* Two unused bytes + addresses */
|
||||
return 2 + p->length; /* Type + len + extension data */
|
||||
}
|
||||
#else
|
||||
#define add_rreq_extensions(p) 0 /* Don't add anything */
|
||||
#endif
|
||||
|
||||
static void
|
||||
send_rreq(uip_ipaddr_t *addr)
|
||||
{
|
||||
struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
|
||||
int len;
|
||||
|
||||
print_debug("send RREQ for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
|
||||
|
||||
rm->type = UAODV_RREQ_TYPE;
|
||||
rm->dest_seqno = last_known_seqno(addr);
|
||||
if(rm->dest_seqno == 0)
|
||||
rm->flags = UAODV_RREQ_UNKSEQNO;
|
||||
else
|
||||
rm->flags = 0;
|
||||
rm->reserved = 0;
|
||||
rm->hop_count = 0;
|
||||
rm->rreq_id = uip_htonl(rreq_id++);
|
||||
uip_ipaddr_copy(&rm->dest_addr, addr);
|
||||
uip_gethostaddr(&rm->orig_addr);
|
||||
my_hseqno++; /* Always */
|
||||
rm->orig_seqno = uip_htonl(my_hseqno);
|
||||
bcastconn->ttl = MY_NET_DIAMETER;
|
||||
len = sizeof(struct uaodv_msg_rreq);
|
||||
len += add_rreq_extensions(rm + 1);
|
||||
uip_udp_packet_send(bcastconn, rm, len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_rrep(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, uip_ipaddr_t *orig,
|
||||
uint32_t *seqno, unsigned hop_count)
|
||||
{
|
||||
struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
|
||||
|
||||
print_debug("send RREP orig=%d.%d.%d.%d hops=%d\n",
|
||||
uip_ipaddr_to_quad(orig), hop_count);
|
||||
|
||||
rm->type = UAODV_RREP_TYPE;
|
||||
rm->flags = 0;
|
||||
rm->prefix_sz = 0; /* I.e a /32 route. */
|
||||
rm->hop_count = hop_count;
|
||||
uip_ipaddr_copy(&rm->orig_addr, orig);
|
||||
rm->dest_seqno = *seqno;
|
||||
uip_ipaddr_copy(&rm->dest_addr, dest);
|
||||
rm->lifetime = UIP_HTONL(MY_ROUTE_TIMEOUT);
|
||||
sendto(nexthop, rm, sizeof(struct uaodv_msg_rrep));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_rerr(uip_ipaddr_t *addr, uint32_t *seqno)
|
||||
{
|
||||
struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
|
||||
|
||||
print_debug("send RERR for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
|
||||
|
||||
rm->type = UAODV_RERR_TYPE;
|
||||
rm->reserved = 0;
|
||||
rm->dest_count = 1;
|
||||
uip_ipaddr_copy(&rm->unreach[0].addr, addr);
|
||||
rm->unreach[0].seqno = *seqno;
|
||||
if(*seqno == 0)
|
||||
rm->flags = UAODV_RERR_UNKNOWN;
|
||||
else
|
||||
rm->flags = 0;
|
||||
|
||||
uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_incoming_rreq(void)
|
||||
{
|
||||
struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
|
||||
uip_ipaddr_t dest_addr, orig_addr;
|
||||
struct uaodv_rt_entry *rt, *fw = NULL;
|
||||
|
||||
print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u"
|
||||
" orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n",
|
||||
uip_ipaddr_to_quad(&BUF->srcipaddr),
|
||||
uip_ipaddr_to_quad(&BUF->destipaddr),
|
||||
BUF->ttl,
|
||||
uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno),
|
||||
rm->hop_count,
|
||||
uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno));
|
||||
|
||||
if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
|
||||
return; /* RREQ looped back! */
|
||||
}
|
||||
|
||||
#ifdef CC2420_RADIO
|
||||
{
|
||||
int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
|
||||
|
||||
if(ret == REMOTE_YES) {
|
||||
print_debug("RREQ drop is remote\n");
|
||||
return;
|
||||
} else if (ret == REMOTE_NO) {
|
||||
/* Is neigbour, accept it. */
|
||||
} else if(cc2420_last_rssi < RSSI_THRESHOLD) {
|
||||
print_debug("RREQ drop %d %d\n", cc2420_last_rssi,
|
||||
cc2420_last_correlation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef AODV_BAD_HOP_EXTENSION
|
||||
if(uip_len > (sizeof(*rm) + 2)) {
|
||||
struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm));
|
||||
uint8_t *end = uip_appdata + uip_len;
|
||||
for(;
|
||||
(uint8_t *)ext < end;
|
||||
ext = (void *)((uint8_t *)ext + ext->length + 2)) {
|
||||
uint8_t *eend = (uint8_t *)ext + ext->length;
|
||||
if(eend > end)
|
||||
eend = end;
|
||||
|
||||
if(ext->type == RREQ_BAD_HOP_EXT) {
|
||||
uip_ipaddr_t *a;
|
||||
for(a = ext->addrs; (uint8_t *)a < eend; a++) {
|
||||
if(uip_ipaddr_cmp(a, &uip_hostaddr)) {
|
||||
print_debug("BAD_HOP drop\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* AODV_BAD_HOP_EXTENSION */
|
||||
|
||||
/* New reverse route? */
|
||||
rt = uaodv_rt_lookup(&rm->orig_addr);
|
||||
if(rt == NULL
|
||||
|| (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */
|
||||
|| (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
|
||||
&& rm->hop_count < rt->hop_count)) { /* Better route. */
|
||||
print_debug("Inserting1\n");
|
||||
rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
|
||||
rm->hop_count, &rm->orig_seqno);
|
||||
}
|
||||
|
||||
/* Check if it is for our address or a fresh route. */
|
||||
if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)
|
||||
|| rm->flags & UAODV_RREQ_DESTONLY) {
|
||||
fw = NULL;
|
||||
} else {
|
||||
fw = uaodv_rt_lookup(&rm->dest_addr);
|
||||
if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
|
||||
&& fw != NULL
|
||||
&& SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
|
||||
fw = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (fw != NULL) {
|
||||
uint32_t net_seqno;
|
||||
|
||||
print_debug("RREQ for known route\n");
|
||||
uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
|
||||
uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
|
||||
net_seqno = uip_htonl(fw->hseqno);
|
||||
send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
|
||||
fw->hop_count + 1);
|
||||
} else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) {
|
||||
uint32_t net_seqno;
|
||||
|
||||
print_debug("RREQ for our address\n");
|
||||
uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
|
||||
uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
|
||||
|
||||
my_hseqno++;
|
||||
if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
|
||||
&& SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) {
|
||||
print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */
|
||||
my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
|
||||
}
|
||||
net_seqno = uip_htonl(my_hseqno);
|
||||
send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0);
|
||||
} else if(BUF->ttl > 1) {
|
||||
int len;
|
||||
|
||||
/* Have we seen this RREQ before? */
|
||||
if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
|
||||
print_debug("RREQ cached, not fwd\n");
|
||||
return;
|
||||
}
|
||||
fwc_add(&rm->orig_addr, &rm->rreq_id);
|
||||
|
||||
print_debug("RREQ fwd\n");
|
||||
rm->hop_count++;
|
||||
bcastconn->ttl = BUF->ttl - 1;
|
||||
len = sizeof(struct uaodv_msg_rreq);
|
||||
len += add_rreq_extensions(rm + 1);
|
||||
uip_udp_packet_send(bcastconn, rm, len);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_incoming_rrep(void)
|
||||
{
|
||||
struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
|
||||
struct uaodv_rt_entry *rt;
|
||||
|
||||
/* Useless HELLO message? */
|
||||
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
|
||||
#ifdef AODV_RESPOND_TO_HELLOS
|
||||
uint32_t net_seqno;
|
||||
#ifdef CC2420_RADIO
|
||||
int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
|
||||
|
||||
if(ret == REMOTE_YES) {
|
||||
print_debug("HELLO drop is remote\n");
|
||||
return;
|
||||
} else if (ret == REMOTE_NO) {
|
||||
/* Is neigbour, accept it. */
|
||||
} else if(cc2420_last_rssi < RSSI_THRESHOLD) {
|
||||
print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Sometimes it helps to send a non-requested RREP in response! */
|
||||
net_seqno = uip_htonl(my_hseqno);
|
||||
send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d"
|
||||
" dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n",
|
||||
uip_ipaddr_to_quad(&BUF->srcipaddr),
|
||||
uip_ipaddr_to_quad(&BUF->destipaddr),
|
||||
uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno),
|
||||
rm->hop_count,
|
||||
uip_ipaddr_to_quad(&rm->orig_addr));
|
||||
|
||||
rt = uaodv_rt_lookup(&rm->dest_addr);
|
||||
|
||||
/* New forward route? */
|
||||
if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) {
|
||||
print_debug("Inserting3\n");
|
||||
rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(),
|
||||
rm->hop_count, &rm->dest_seqno);
|
||||
#ifdef CC2420_RADIO
|
||||
/* This link is ok since he is unicasting back to us! */
|
||||
cc2420_recv_ok(uip_udp_sender());
|
||||
print_debug("RREP recv ok %d %d\n",
|
||||
cc2420_last_rssi, cc2420_last_correlation);
|
||||
#endif
|
||||
} else {
|
||||
print_debug("Not inserting\n");
|
||||
}
|
||||
|
||||
/* Forward RREP towards originator? */
|
||||
if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
|
||||
print_debug("ROUTE FOUND\n");
|
||||
if(rm->flags & UAODV_RREP_ACK) {
|
||||
struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata;
|
||||
ack->type = UAODV_RREP_ACK_TYPE;
|
||||
ack->reserved = 0;
|
||||
sendto(uip_udp_sender(), ack, sizeof(*ack));
|
||||
}
|
||||
} else {
|
||||
rt = uaodv_rt_lookup(&rm->orig_addr);
|
||||
|
||||
if(rt == NULL) {
|
||||
print_debug("RREP received, but no route back to originator... :-( \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(rm->flags & UAODV_RREP_ACK) {
|
||||
print_debug("RREP with ACK request (ignored)!\n");
|
||||
/* Don't want any RREP-ACKs in return! */
|
||||
rm->flags &= ~UAODV_RREP_ACK;
|
||||
}
|
||||
|
||||
rm->hop_count++;
|
||||
|
||||
print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop));
|
||||
|
||||
sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep));
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_incoming_rerr(void)
|
||||
{
|
||||
struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
|
||||
struct uaodv_rt_entry *rt;
|
||||
|
||||
print_debug("RERR %d.%d.%d.%d -> %d.%d.%d.%d"
|
||||
" unreach=%d.%d.%d.%d seq=%lu\n",
|
||||
uip_ipaddr_to_quad(&BUF->srcipaddr),
|
||||
uip_ipaddr_to_quad(&BUF->destipaddr),
|
||||
uip_ipaddr_to_quad((uip_ipaddr_t *)&rm->unreach[0]),
|
||||
uip_ntohl(rm->unreach[0].seqno));
|
||||
|
||||
if(uip_ipaddr_cmp(&rm->unreach[0].addr, &uip_hostaddr))
|
||||
return;
|
||||
|
||||
rt = uaodv_rt_lookup_any(&rm->unreach[0].addr);
|
||||
if(rt != NULL && uip_ipaddr_cmp(&rt->nexthop, uip_udp_sender())) {
|
||||
if((rm->flags & UAODV_RERR_UNKNOWN) || rm->unreach[0].seqno == 0
|
||||
|| SCMP32(rt->hseqno, uip_ntohl(rm->unreach[0].seqno)) <= 0) {
|
||||
rt->is_bad = 1;
|
||||
if(rm->flags & UAODV_RERR_UNKNOWN) {
|
||||
rm->flags &= ~UAODV_RERR_UNKNOWN;
|
||||
rm->unreach[0].seqno = uip_htonl(rt->hseqno);
|
||||
}
|
||||
print_debug("RERR rebroadcast\n");
|
||||
uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_incoming_packet(void)
|
||||
{
|
||||
struct uaodv_msg *m = (struct uaodv_msg *)uip_appdata;
|
||||
|
||||
/* print_debug("New UDP data, AODV packet type %d\n", m->type);*/
|
||||
switch(m->type) {
|
||||
case UAODV_RREQ_TYPE:
|
||||
handle_incoming_rreq();
|
||||
break;
|
||||
|
||||
case UAODV_RREP_TYPE:
|
||||
handle_incoming_rrep();
|
||||
break;
|
||||
|
||||
case UAODV_RERR_TYPE:
|
||||
handle_incoming_rerr();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static enum {
|
||||
COMMAND_NONE,
|
||||
COMMAND_SEND_RREQ,
|
||||
COMMAND_SEND_RERR,
|
||||
} command;
|
||||
|
||||
static uip_ipaddr_t bad_dest;
|
||||
static uint32_t bad_seqno; /* In network byte order! */
|
||||
|
||||
void
|
||||
uaodv_bad_dest(uip_ipaddr_t *dest)
|
||||
{
|
||||
struct uaodv_rt_entry *rt = uaodv_rt_lookup_any(dest);
|
||||
|
||||
if(rt == NULL)
|
||||
bad_seqno = 0; /* Or flag this in RERR? */
|
||||
else {
|
||||
rt->is_bad = 1;
|
||||
bad_seqno = uip_htonl(rt->hseqno);
|
||||
}
|
||||
|
||||
uip_ipaddr_copy(&bad_dest, dest);
|
||||
command = COMMAND_SEND_RERR;
|
||||
process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
|
||||
}
|
||||
|
||||
static uip_ipaddr_t rreq_addr;
|
||||
static struct timer next_time;
|
||||
|
||||
struct uaodv_rt_entry *
|
||||
uaodv_request_route_to(uip_ipaddr_t *host)
|
||||
{
|
||||
struct uaodv_rt_entry *route = uaodv_rt_lookup(host);
|
||||
|
||||
if(route != NULL) {
|
||||
uaodv_rt_lru(route);
|
||||
return route;
|
||||
}
|
||||
|
||||
/*
|
||||
* Broadcast protocols must be rate-limited!
|
||||
*/
|
||||
if(!timer_expired(&next_time)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(command != COMMAND_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uip_ipaddr_copy(&rreq_addr, host);
|
||||
command = COMMAND_SEND_RREQ;
|
||||
process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
|
||||
timer_set(&next_time, CLOCK_SECOND/8); /* Max 10/s per RFC3561. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PROCESS_THREAD(uaodv_process, ev, data)
|
||||
{
|
||||
PROCESS_EXITHANDLER(goto exit);
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("uaodv_process starting %lu\n", (unsigned long) my_hseqno);
|
||||
|
||||
bcastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
|
||||
unicastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
|
||||
if(ev == tcpip_event) {
|
||||
if(uip_newdata()) {
|
||||
handle_incoming_packet();
|
||||
continue;
|
||||
}
|
||||
if(uip_poll()) {
|
||||
if(command == COMMAND_SEND_RREQ) {
|
||||
if(uaodv_rt_lookup(&rreq_addr) == NULL)
|
||||
send_rreq(&rreq_addr);
|
||||
} else if (command == COMMAND_SEND_RERR) {
|
||||
send_rerr(&bad_dest, &bad_seqno);
|
||||
}
|
||||
command = COMMAND_NONE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(ev == PROCESS_EVENT_MSG) {
|
||||
tcpip_poll_udp(bcastconn);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
command = COMMAND_NONE;
|
||||
uaodv_rt_flush_all();
|
||||
uip_udp_remove(bcastconn);
|
||||
bcastconn = NULL;
|
||||
uip_udp_remove(unicastconn);
|
||||
unicastconn = NULL;
|
||||
printf("uaodv_process exiting\n");
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef UAODV_H_
|
||||
#define UAODV_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "uaodv-rt.h"
|
||||
|
||||
PROCESS_NAME(uaodv_process);
|
||||
|
||||
struct uaodv_rt_entry * uaodv_request_route_to(uip_ipaddr_t *host);
|
||||
void uaodv_bad_dest(uip_ipaddr_t *);
|
||||
|
||||
#endif /* UAODV_H_ */
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
|
||||
PROCESS(uip_fw_process, "IP forwarding");
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(uip_fw_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
tcpip_set_outputfunc(uip_fw_output);
|
||||
|
||||
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef UIP_FW_DRV_H_
|
||||
#define UIP_FW_DRV_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
|
||||
PROCESS_NAME(uip_fw_process);
|
||||
|
||||
#endif /* UIP_FW_DRV_H_ */
|
@ -1,536 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \addtogroup uip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup uipfw uIP packet forwarding
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* uIP packet forwarding.
|
||||
* \author Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
* This file implements a number of simple functions which do packet
|
||||
* forwarding over multiple network interfaces with uIP.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ip/uip_arch.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#ifdef AODV_COMPLIANCE
|
||||
#include "net/ipv4/uaodv-def.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The list of registered network interfaces.
|
||||
*/
|
||||
static struct uip_fw_netif *netifs = NULL;
|
||||
|
||||
/*
|
||||
* A pointer to the default network interface.
|
||||
*/
|
||||
static struct uip_fw_netif *defaultnetif = NULL;
|
||||
|
||||
struct tcpip_hdr {
|
||||
/* IP header. */
|
||||
uint8_t vhl,
|
||||
tos;
|
||||
uint16_t len,
|
||||
ipid,
|
||||
ipoffset;
|
||||
uint8_t ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
|
||||
/* TCP header. */
|
||||
uint16_t srcport,
|
||||
destport;
|
||||
uint8_t seqno[4],
|
||||
ackno[4],
|
||||
tcpoffset,
|
||||
flags,
|
||||
wnd[2];
|
||||
uint16_t tcpchksum;
|
||||
uint8_t urgp[2];
|
||||
uint8_t optdata[4];
|
||||
};
|
||||
|
||||
struct icmpip_hdr {
|
||||
/* IP header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
/* ICMP (echo) header. */
|
||||
uint8_t type, icode;
|
||||
uint16_t icmpchksum;
|
||||
uint16_t id, seqno;
|
||||
uint8_t payload[1];
|
||||
};
|
||||
|
||||
/* ICMP ECHO. */
|
||||
#define ICMP_ECHO 8
|
||||
|
||||
/* ICMP TIME-EXCEEDED. */
|
||||
#define ICMP_TE 11
|
||||
|
||||
/*
|
||||
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
|
||||
*/
|
||||
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/*
|
||||
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
|
||||
*/
|
||||
#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/*
|
||||
* Certain fields of an IP packet that are used for identifying
|
||||
* duplicate packets.
|
||||
*/
|
||||
struct fwcache_entry {
|
||||
uint16_t timer;
|
||||
|
||||
uip_ipaddr_t srcipaddr;
|
||||
uip_ipaddr_t destipaddr;
|
||||
uint16_t ipid;
|
||||
uint8_t proto;
|
||||
uint8_t unused;
|
||||
|
||||
#if notdef
|
||||
uint16_t payload[2];
|
||||
#endif
|
||||
|
||||
#if UIP_REASSEMBLY > 0
|
||||
uint16_t len, offset;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of packets to remember when looking for duplicates.
|
||||
*/
|
||||
#ifdef UIP_CONF_FWCACHE_SIZE
|
||||
#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
|
||||
#else
|
||||
#define FWCACHE_SIZE 2
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* A cache of packet header fields which are used for
|
||||
* identifying duplicate packets.
|
||||
*/
|
||||
static struct fwcache_entry fwcache[FWCACHE_SIZE];
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* The time that a packet cache is active.
|
||||
*/
|
||||
#define FW_TIME 20
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initialize the uIP packet forwarding module.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_init(void)
|
||||
{
|
||||
struct uip_fw_netif *t;
|
||||
defaultnetif = NULL;
|
||||
while(netifs != NULL) {
|
||||
t = netifs;
|
||||
netifs = netifs->next;
|
||||
t->next = NULL;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Check if an IP address is within the network defined by an IP
|
||||
* address and a netmask.
|
||||
*
|
||||
* \param ipaddr The IP address to be checked.
|
||||
* \param netipaddr The IP address of the network.
|
||||
* \param netmask The netmask of the network.
|
||||
*
|
||||
* \return Non-zero if IP address is in network, zero otherwise.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static unsigned char
|
||||
ipaddr_maskcmp(uip_ipaddr_t *ipaddr,
|
||||
uip_ipaddr_t *netipaddr,
|
||||
uip_ipaddr_t *netmask)
|
||||
{
|
||||
return (ipaddr->u16[0] & netmask->u16[0]) == (netipaddr->u16[0] & netmask->u16[0]) &&
|
||||
(ipaddr->u16[1] & netmask->u16[1]) == (netipaddr->u16[1] & netmask->u16[1]);
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Send out an ICMP TIME-EXCEEDED message.
|
||||
*
|
||||
* This function replaces the packet in the uip_buf buffer with the
|
||||
* ICMP packet.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void
|
||||
time_exceeded(void)
|
||||
{
|
||||
|
||||
/* We don't send out ICMP errors for ICMP messages (unless they are pings). */
|
||||
if(ICMPBUF->proto == UIP_PROTO_ICMP &&
|
||||
ICMPBUF->type != ICMP_ECHO) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
/* Copy fields from packet header into payload of this ICMP packet. */
|
||||
memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
|
||||
|
||||
/* Set the ICMP type and code. */
|
||||
ICMPBUF->type = ICMP_TE;
|
||||
ICMPBUF->icode = 0;
|
||||
|
||||
/* Calculate the ICMP checksum. */
|
||||
ICMPBUF->icmpchksum = 0;
|
||||
ICMPBUF->icmpchksum = ~uip_chksum((uint16_t *)&(ICMPBUF->type), 36);
|
||||
|
||||
/* Set the IP destination address to be the source address of the
|
||||
original packet. */
|
||||
uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
|
||||
|
||||
/* Set our IP address as the source address. */
|
||||
uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
|
||||
|
||||
/* The size of the ICMP time exceeded packet is 36 + the size of the
|
||||
IP header (20) = 56. */
|
||||
uip_len = 56;
|
||||
ICMPBUF->len[0] = 0;
|
||||
ICMPBUF->len[1] = (uint8_t)uip_len;
|
||||
|
||||
/* Fill in the other fields in the IP header. */
|
||||
ICMPBUF->vhl = 0x45;
|
||||
ICMPBUF->tos = 0;
|
||||
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
|
||||
ICMPBUF->ttl = UIP_TTL;
|
||||
ICMPBUF->proto = UIP_PROTO_ICMP;
|
||||
|
||||
/* Calculate IP checksum. */
|
||||
ICMPBUF->ipchksum = 0;
|
||||
ICMPBUF->ipchksum = ~(uip_ipchksum());
|
||||
|
||||
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Register a packet in the forwarding cache so that it won't be
|
||||
* forwarded again.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static void
|
||||
fwcache_register(void)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
int i, oldest;
|
||||
|
||||
oldest = FW_TIME;
|
||||
fw = NULL;
|
||||
|
||||
/* Find the oldest entry in the cache. */
|
||||
for(i = 0; i < FWCACHE_SIZE; ++i) {
|
||||
if(fwcache[i].timer == 0) {
|
||||
fw = &fwcache[i];
|
||||
break;
|
||||
} else if(fwcache[i].timer <= oldest) {
|
||||
fw = &fwcache[i];
|
||||
oldest = fwcache[i].timer;
|
||||
}
|
||||
}
|
||||
|
||||
fw->timer = FW_TIME;
|
||||
fw->ipid = BUF->ipid;
|
||||
uip_ipaddr_copy(&fw->srcipaddr, &BUF->srcipaddr);
|
||||
uip_ipaddr_copy(&fw->destipaddr, &BUF->destipaddr);
|
||||
fw->proto = BUF->proto;
|
||||
#if notdef
|
||||
fw->payload[0] = BUF->srcport;
|
||||
fw->payload[1] = BUF->destport;
|
||||
#endif
|
||||
#if UIP_REASSEMBLY > 0
|
||||
fw->len = BUF->len;
|
||||
fw->offset = BUF->ipoffset;
|
||||
#endif
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \internal
|
||||
* Find a network interface for the IP packet in uip_buf.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static struct uip_fw_netif *
|
||||
find_netif(void)
|
||||
{
|
||||
struct uip_fw_netif *netif;
|
||||
|
||||
/* Walk through every network interface to check for a match. */
|
||||
for(netif = netifs; netif != NULL; netif = netif->next) {
|
||||
if(ipaddr_maskcmp(&BUF->destipaddr, &netif->ipaddr,
|
||||
&netif->netmask)) {
|
||||
/* If there was a match, we break the loop. */
|
||||
return netif;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no matching netif was found, we use default netif. */
|
||||
return defaultnetif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Output an IP packet on the correct network interface.
|
||||
*
|
||||
* The IP packet should be present in the uip_buf buffer and its
|
||||
* length in the global uip_len variable.
|
||||
*
|
||||
* \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
|
||||
* transmission was attempted and that no packet was sent.
|
||||
*
|
||||
* \retval UIP_FW_NOROUTE No suitable network interface could be found
|
||||
* for the outbound packet, and the packet was not sent.
|
||||
*
|
||||
* \return The return value from the actual network interface output
|
||||
* function is passed unmodified as a return value.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uip_fw_output(void)
|
||||
{
|
||||
struct uip_fw_netif *netif;
|
||||
#if UIP_BROADCAST
|
||||
const struct uip_udpip_hdr *udp = (void *)BUF;
|
||||
#endif /* UIP_BROADCAST */
|
||||
|
||||
if(uip_len == 0) {
|
||||
return UIP_FW_ZEROLEN;
|
||||
}
|
||||
|
||||
fwcache_register();
|
||||
|
||||
#if UIP_BROADCAST
|
||||
/* Link local broadcasts go out on all interfaces. */
|
||||
if(uip_ipaddr_cmp(&udp->destipaddr, &uip_broadcast_addr)) {
|
||||
if(defaultnetif != NULL) {
|
||||
defaultnetif->output();
|
||||
}
|
||||
for(netif = netifs; netif != NULL; netif = netif->next) {
|
||||
netif->output();
|
||||
}
|
||||
return UIP_FW_OK;
|
||||
}
|
||||
#endif /* UIP_BROADCAST */
|
||||
|
||||
netif = find_netif();
|
||||
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
|
||||
netif->output,
|
||||
uip_len);*/
|
||||
|
||||
if(netif == NULL) {
|
||||
return UIP_FW_NOROUTE;
|
||||
}
|
||||
/* If we now have found a suitable network interface, we call its
|
||||
output function to send out the packet. */
|
||||
return netif->output();
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Forward an IP packet in the uip_buf buffer.
|
||||
*
|
||||
*
|
||||
*
|
||||
* \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
|
||||
* the packet should be processed locally.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uip_fw_forward(void)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
|
||||
/* First check if the packet is destined for ourselves and return 0
|
||||
to indicate that the packet should be processed locally. */
|
||||
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
|
||||
#ifdef AODV_COMPLIANCE
|
||||
#define udp ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
if(udp->proto == UIP_PROTO_UDP && udp->destport == UIP_HTONS(UAODV_UDPPORT)) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we use ping IP address configuration, and our IP address is
|
||||
not yet configured, we should intercept all ICMP echo packets. */
|
||||
#if UIP_PINGADDRCONF
|
||||
if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) &&
|
||||
BUF->proto == UIP_PROTO_ICMP &&
|
||||
ICMPBUF->type == ICMP_ECHO) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
#endif /* UIP_PINGADDRCONF */
|
||||
|
||||
/* Check if the packet is in the forwarding cache already, and if so
|
||||
we drop it. */
|
||||
|
||||
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
|
||||
if(fw->timer != 0 &&
|
||||
#if UIP_REASSEMBLY > 0
|
||||
fw->len == BUF->len &&
|
||||
fw->offset == BUF->ipoffset &&
|
||||
#endif
|
||||
fw->ipid == BUF->ipid &&
|
||||
uip_ipaddr_cmp(&fw->srcipaddr, &BUF->srcipaddr) &&
|
||||
uip_ipaddr_cmp(&fw->destipaddr, &BUF->destipaddr) &&
|
||||
#if notdef
|
||||
fw->payload[0] == BUF->srcport &&
|
||||
fw->payload[1] == BUF->destport &&
|
||||
#endif
|
||||
fw->proto == BUF->proto) {
|
||||
/* Drop packet. */
|
||||
return UIP_FW_FORWARDED;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the TTL reaches zero we produce an ICMP time exceeded message
|
||||
in the uip_buf buffer and forward that packet back to the sender
|
||||
of the packet. */
|
||||
|
||||
if(BUF->ttl <= 1) {
|
||||
/* No time exceeded for broadcasts and multicasts! */
|
||||
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
time_exceeded();
|
||||
}
|
||||
|
||||
/* Decrement the TTL (time-to-live) value in the IP header */
|
||||
BUF->ttl = BUF->ttl - 1;
|
||||
|
||||
/* Update the IP checksum. */
|
||||
if(BUF->ipchksum >= UIP_HTONS(0xffff - 0x0100)) {
|
||||
BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100) + 1;
|
||||
} else {
|
||||
BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100);
|
||||
}
|
||||
|
||||
if(uip_len > 0) {
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
|
||||
uip_fw_output();
|
||||
}
|
||||
|
||||
#if UIP_BROADCAST
|
||||
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
|
||||
return UIP_FW_LOCAL;
|
||||
}
|
||||
#endif /* UIP_BROADCAST */
|
||||
|
||||
/* Return non-zero to indicate that the packet was forwarded and that no
|
||||
other processing should be made. */
|
||||
return UIP_FW_FORWARDED;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Register a network interface with the forwarding module.
|
||||
*
|
||||
* \param netif A pointer to the network interface that is to be
|
||||
* registered.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_register(struct uip_fw_netif *netif)
|
||||
{
|
||||
netif->next = netifs;
|
||||
netifs = netif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Register a default network interface.
|
||||
*
|
||||
* All packets that don't go out on any of the other interfaces will
|
||||
* be routed to the default interface.
|
||||
*
|
||||
* \param netif A pointer to the network interface that is to be
|
||||
* registered.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_default(struct uip_fw_netif *netif)
|
||||
{
|
||||
defaultnetif = netif;
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Perform periodic processing.
|
||||
*/
|
||||
/*------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_fw_periodic(void)
|
||||
{
|
||||
struct fwcache_entry *fw;
|
||||
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
|
||||
if(fw->timer > 0) {
|
||||
--fw->timer;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
/** @} */
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* uIP packet forwarding header file.
|
||||
* \author Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup uipfw
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef UIP_FW_H_
|
||||
#define UIP_FW_H_
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
|
||||
/**
|
||||
* Representation of a uIP network interface.
|
||||
*/
|
||||
struct uip_fw_netif {
|
||||
struct uip_fw_netif *next; /**< Pointer to the next interface when
|
||||
linked in a list. */
|
||||
uip_ipaddr_t ipaddr; /**< The IP address of this interface. */
|
||||
uip_ipaddr_t netmask; /**< The netmask of the interface. */
|
||||
uint8_t (* output)(void);
|
||||
/**< A pointer to the function that
|
||||
sends a packet. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiating macro for a uIP network interface.
|
||||
*
|
||||
* Example:
|
||||
\code
|
||||
struct uip_fw_netif slipnetif =
|
||||
{UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
|
||||
\endcode
|
||||
* \param ip1,ip2,ip3,ip4 The IP address of the network interface.
|
||||
*
|
||||
* \param nm1,nm2,nm3,nm4 The netmask of the network interface.
|
||||
*
|
||||
* \param outputfunc A pointer to the output function of the network interface.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
|
||||
NULL, \
|
||||
{ {ip1, ip2, ip3, ip4} }, \
|
||||
{ {nm1, nm2, nm3, nm4} }, \
|
||||
outputfunc
|
||||
|
||||
/**
|
||||
* Set the IP address of a network interface.
|
||||
*
|
||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
*
|
||||
* \param addr A pointer to an IP address.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define uip_fw_setipaddr(netif, addr) \
|
||||
do { (netif)->ipaddr[0] = ((uint16_t *)(addr))[0]; \
|
||||
(netif)->ipaddr[1] = ((uint16_t *)(addr))[1]; } while(0)
|
||||
/**
|
||||
* Set the netmask of a network interface.
|
||||
*
|
||||
* \param netif A pointer to the uip_fw_netif structure for the network interface.
|
||||
*
|
||||
* \param addr A pointer to an IP address representing the netmask.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define uip_fw_setnetmask(netif, addr) \
|
||||
do { (netif)->netmask[0] = ((uint16_t *)(addr))[0]; \
|
||||
(netif)->netmask[1] = ((uint16_t *)(addr))[1]; } while(0)
|
||||
|
||||
void uip_fw_init(void);
|
||||
uint8_t uip_fw_forward(void);
|
||||
uint8_t uip_fw_output(void);
|
||||
void uip_fw_register(struct uip_fw_netif *netif);
|
||||
void uip_fw_default(struct uip_fw_netif *netif);
|
||||
void uip_fw_periodic(void);
|
||||
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet should be
|
||||
* processed locally.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_LOCAL 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that something went OK.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_OK 0
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet was forwarded.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_FORWARDED 1
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a zero-length packet
|
||||
* transmission was attempted, and that no packet was sent.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_ZEROLEN 2
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that was too large
|
||||
* for the outbound network interface was detected.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_TOOLARGE 3
|
||||
|
||||
/**
|
||||
* An error message that indicates that no suitable interface could be
|
||||
* found for an outbound packet.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_NOROUTE 4
|
||||
|
||||
/**
|
||||
* An error message that indicates that a packet that should be
|
||||
* forwarded or output was dropped.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_FW_DROPPED 5
|
||||
|
||||
|
||||
#endif /* UIP_FW_H_ */
|
||||
|
||||
/** @} */
|
@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Database of link-local neighbors, used by IPv6 code and
|
||||
* to be used by a future ARP code rewrite.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#include "net/ipv4/uip-neighbor.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_TIME 128
|
||||
|
||||
#ifdef UIP_NEIGHBOR_CONF_ENTRIES
|
||||
#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
|
||||
#else /* UIP_NEIGHBOR_CONF_ENTRIES */
|
||||
#define ENTRIES 8
|
||||
#endif /* UIP_NEIGHBOR_CONF_ENTRIES */
|
||||
|
||||
struct neighbor_entry {
|
||||
uip_ipaddr_t ipaddr;
|
||||
struct uip_neighbor_addr addr;
|
||||
uint8_t time;
|
||||
};
|
||||
static struct neighbor_entry entries[ENTRIES];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_neighbor_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < ENTRIES; ++i) {
|
||||
entries[i].time = MAX_TIME;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_neighbor_periodic(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < ENTRIES; ++i) {
|
||||
if(entries[i].time < MAX_TIME) {
|
||||
entries[i].time++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr)
|
||||
{
|
||||
int i, oldest;
|
||||
uint8_t oldest_time;
|
||||
|
||||
/* printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
|
||||
addr->addr.addr[4], addr->addr.addr[5]);*/
|
||||
|
||||
/* Find the first unused entry or the oldest used entry. */
|
||||
oldest_time = 0;
|
||||
oldest = 0;
|
||||
for(i = 0; i < ENTRIES; ++i) {
|
||||
if(entries[i].time == MAX_TIME) {
|
||||
oldest = i;
|
||||
break;
|
||||
}
|
||||
if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) {
|
||||
oldest = i;
|
||||
break;
|
||||
}
|
||||
if(entries[i].time > oldest_time) {
|
||||
oldest = i;
|
||||
oldest_time = entries[i].time;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the oldest or first free entry (either pointed to by the
|
||||
"oldest" variable). */
|
||||
entries[oldest].time = 0;
|
||||
uip_ipaddr_copy(&entries[oldest].ipaddr, ipaddr);
|
||||
memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static struct neighbor_entry *
|
||||
find_entry(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < ENTRIES; ++i) {
|
||||
if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) {
|
||||
return &entries[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_neighbor_update(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
struct neighbor_entry *e;
|
||||
|
||||
e = find_entry(ipaddr);
|
||||
if(e != NULL) {
|
||||
e->time = 0;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct uip_neighbor_addr *
|
||||
uip_neighbor_lookup(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
struct neighbor_entry *e;
|
||||
|
||||
e = find_entry(ipaddr);
|
||||
if(e != NULL) {
|
||||
/* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
|
||||
e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
|
||||
|
||||
return &e->addr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Header file for database of link-local neighbors, used by
|
||||
* IPv6 code and to be used by future ARP code.
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef UIP_NEIGHBOR_H_
|
||||
#define UIP_NEIGHBOR_H_
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
|
||||
struct uip_neighbor_addr {
|
||||
#if UIP_NEIGHBOR_CONF_ADDRTYPE
|
||||
UIP_NEIGHBOR_CONF_ADDRTYPE addr;
|
||||
#else
|
||||
struct uip_eth_addr addr;
|
||||
#endif
|
||||
};
|
||||
|
||||
void uip_neighbor_init(void);
|
||||
void uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr);
|
||||
void uip_neighbor_update(uip_ipaddr_t *ipaddr);
|
||||
struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t *ipaddr);
|
||||
void uip_neighbor_periodic(void);
|
||||
|
||||
#endif /* UIP-NEIGHBOR_H_ */
|
@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Code for tunnelling uIP packets over the Rime mesh routing module
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net/rime/rime.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#include "net/ipv4/uip-over-mesh.h"
|
||||
|
||||
#define ROUTE_TRICKLE_INTERVAL CLOCK_SECOND * 32
|
||||
#define ROUTE_DISCOVERY_INTERVAL CLOCK_SECOND * 4
|
||||
#define ROUTE_TIMEOUT CLOCK_SECOND * 4
|
||||
|
||||
static struct queuebuf *queued_packet;
|
||||
static linkaddr_t queued_receiver;
|
||||
|
||||
/* Connection for route discovery: */
|
||||
static struct route_discovery_conn route_discovery;
|
||||
|
||||
/* Connection for sending data packets to the next hop node: */
|
||||
static struct unicast_conn dataconn;
|
||||
|
||||
/* Connection for sending gateway announcement message to the entire
|
||||
network: */
|
||||
static struct trickle_conn gateway_announce_conn;
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
static struct uip_fw_netif *gw_netif;
|
||||
static linkaddr_t gateway;
|
||||
static uip_ipaddr_t netaddr, netmask;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
recv_data(struct unicast_conn *c, const linkaddr_t *from)
|
||||
{
|
||||
struct route_entry *e;
|
||||
linkaddr_t source;
|
||||
|
||||
uip_len = packetbuf_copyto(&uip_buf[UIP_LLH_LEN]);
|
||||
|
||||
source.u8[0] = BUF->srcipaddr.u8[2];
|
||||
source.u8[1] = BUF->srcipaddr.u8[3];
|
||||
|
||||
e = route_lookup(&source);
|
||||
if(e == NULL) {
|
||||
route_add(&source, from, 10, 0);
|
||||
} else {
|
||||
route_refresh(e);
|
||||
}
|
||||
|
||||
/* If we received data via a gateway, we refresh the gateway route.
|
||||
* Note: we refresh OUR gateway route, although we are not sure it forwarded the data. */
|
||||
if(!uip_ipaddr_maskcmp(&BUF->srcipaddr, &netaddr, &netmask)) {
|
||||
e = route_lookup(&gateway);
|
||||
if(e != NULL) {
|
||||
route_refresh(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PRINTF("uip-over-mesh: %d.%d: recv_data with len %d\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], uip_len);
|
||||
tcpip_input();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_data(linkaddr_t *next)
|
||||
{
|
||||
PRINTF("uip-over-mesh: %d.%d: send_data with len %d\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
|
||||
packetbuf_totlen());
|
||||
unicast_send(&dataconn, next);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
new_route(struct route_discovery_conn *c, const linkaddr_t *to)
|
||||
{
|
||||
struct route_entry *rt;
|
||||
|
||||
if(queued_packet) {
|
||||
PRINTF("uip-over-mesh: new route, sending queued packet\n");
|
||||
|
||||
queuebuf_to_packetbuf(queued_packet);
|
||||
queuebuf_free(queued_packet);
|
||||
queued_packet = NULL;
|
||||
|
||||
rt = route_lookup(&queued_receiver);
|
||||
if(rt) {
|
||||
route_decay(rt);
|
||||
send_data(&queued_receiver);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
timedout(struct route_discovery_conn *c)
|
||||
{
|
||||
PRINTF("uip-over-mesh: packet timed out\n");
|
||||
if(queued_packet) {
|
||||
PRINTF("uip-over-mesh: freeing queued packet\n");
|
||||
queuebuf_free(queued_packet);
|
||||
queued_packet = NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const struct unicast_callbacks data_callbacks = { recv_data };
|
||||
static const struct route_discovery_callbacks rdc = { new_route, timedout };
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct gateway_msg {
|
||||
linkaddr_t gateway;
|
||||
};
|
||||
|
||||
static uint8_t is_gateway;
|
||||
|
||||
static void
|
||||
gateway_announce_recv(struct trickle_conn *c)
|
||||
{
|
||||
struct gateway_msg *msg;
|
||||
msg = packetbuf_dataptr();
|
||||
PRINTF("%d.%d: gateway message: %d.%d\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
|
||||
msg->gateway.u8[0], msg->gateway.u8[1]);
|
||||
|
||||
if(!is_gateway) {
|
||||
uip_over_mesh_set_gateway(&msg->gateway);
|
||||
}
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_over_mesh_make_announced_gateway(void)
|
||||
{
|
||||
struct gateway_msg msg;
|
||||
/* Make this node the gateway node, unless it already is the
|
||||
gateway. */
|
||||
if(!is_gateway) {
|
||||
PRINTF("%d.%d: making myself the gateway\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
|
||||
uip_over_mesh_set_gateway(&linkaddr_node_addr);
|
||||
linkaddr_copy(&(msg.gateway), &linkaddr_node_addr);
|
||||
packetbuf_copyfrom(&msg, sizeof(struct gateway_msg));
|
||||
trickle_send(&gateway_announce_conn);
|
||||
is_gateway = 1;
|
||||
}
|
||||
}
|
||||
const static struct trickle_callbacks trickle_call = {gateway_announce_recv};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_over_mesh_init(uint16_t channels)
|
||||
{
|
||||
|
||||
PRINTF("Our address is %d.%d (%d.%d.%d.%d)\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
|
||||
uip_hostaddr.u8[0], uip_hostaddr.u8[1],
|
||||
uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
|
||||
|
||||
unicast_open(&dataconn, channels, &data_callbacks);
|
||||
route_discovery_open(&route_discovery, ROUTE_DISCOVERY_INTERVAL,
|
||||
channels + 1, &rdc);
|
||||
trickle_open(&gateway_announce_conn, ROUTE_TRICKLE_INTERVAL, channels + 3,
|
||||
&trickle_call);
|
||||
|
||||
route_init();
|
||||
/* Set lifetime to 30 seconds for non-refreshed routes. */
|
||||
route_set_lifetime(30);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uip_over_mesh_send(void)
|
||||
{
|
||||
linkaddr_t receiver;
|
||||
struct route_entry *rt;
|
||||
|
||||
/* This function is called by the uip-fw module to send out an IP
|
||||
packet. We try to send the IP packet to the next hop route, or we
|
||||
queue the packet and send out a route request for the final
|
||||
receiver of the packet. */
|
||||
|
||||
/* Packets destined to this network is sent using mesh, whereas
|
||||
packets destined to a network outside this network is sent towards
|
||||
the gateway node. */
|
||||
|
||||
if(uip_ipaddr_maskcmp(&BUF->destipaddr, &netaddr, &netmask)) {
|
||||
receiver.u8[0] = BUF->destipaddr.u8[2];
|
||||
receiver.u8[1] = BUF->destipaddr.u8[3];
|
||||
} else {
|
||||
if(linkaddr_cmp(&gateway, &linkaddr_node_addr)) {
|
||||
PRINTF("uip_over_mesh_send: I am gateway, packet to %d.%d.%d.%d to local interface\n",
|
||||
uip_ipaddr_to_quad(&BUF->destipaddr));
|
||||
if(gw_netif != NULL) {
|
||||
return gw_netif->output();
|
||||
}
|
||||
return UIP_FW_DROPPED;
|
||||
} else if(linkaddr_cmp(&gateway, &linkaddr_null)) {
|
||||
PRINTF("uip_over_mesh_send: No gateway setup, dropping packet\n");
|
||||
return UIP_FW_OK;
|
||||
} else {
|
||||
PRINTF("uip_over_mesh_send: forwarding packet to %d.%d.%d.%d towards gateway %d.%d\n",
|
||||
uip_ipaddr_to_quad(&BUF->destipaddr),
|
||||
gateway.u8[0], gateway.u8[1]);
|
||||
linkaddr_copy(&receiver, &gateway);
|
||||
}
|
||||
}
|
||||
|
||||
PRINTF("uIP over mesh send to %d.%d with len %d\n",
|
||||
receiver.u8[0], receiver.u8[1],
|
||||
uip_len);
|
||||
|
||||
|
||||
packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
|
||||
rt = route_lookup(&receiver);
|
||||
if(rt == NULL) {
|
||||
PRINTF("uIP over mesh no route to %d.%d\n", receiver.u8[0], receiver.u8[1]);
|
||||
if(queued_packet == NULL) {
|
||||
queued_packet = queuebuf_new_from_packetbuf();
|
||||
linkaddr_copy(&queued_receiver, &receiver);
|
||||
route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
|
||||
} else if(!linkaddr_cmp(&queued_receiver, &receiver)) {
|
||||
route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
|
||||
}
|
||||
} else {
|
||||
route_decay(rt);
|
||||
send_data(&rt->nexthop);
|
||||
}
|
||||
return UIP_FW_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_over_mesh_set_gateway_netif(struct uip_fw_netif *n)
|
||||
{
|
||||
gw_netif = n;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_over_mesh_set_gateway(linkaddr_t *gw)
|
||||
{
|
||||
linkaddr_copy(&gateway, gw);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_over_mesh_set_net(uip_ipaddr_t *addr, uip_ipaddr_t *mask)
|
||||
{
|
||||
uip_ipaddr_copy(&netaddr, addr);
|
||||
uip_ipaddr_copy(&netmask, mask);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Header file for tunnelling uIP over Rime mesh
|
||||
* \author
|
||||
* Adam Dunkels <adam@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef UIP_OVER_MESH_H_
|
||||
#define UIP_OVER_MESH_H_
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
|
||||
void uip_over_mesh_init(uint16_t channels);
|
||||
uint8_t uip_over_mesh_send(void);
|
||||
|
||||
void uip_over_mesh_set_gateway_netif(struct uip_fw_netif *netif);
|
||||
void uip_over_mesh_set_gateway(linkaddr_t *gw);
|
||||
void uip_over_mesh_set_net(uip_ipaddr_t *addr, uip_ipaddr_t *mask);
|
||||
|
||||
void uip_over_mesh_make_announced_gateway(void);
|
||||
|
||||
#endif /* UIP-OVER-MESH_H_ */
|
1973
core/net/ipv4/uip.c
1973
core/net/ipv4/uip.c
File diff suppressed because it is too large
Load Diff
@ -1,440 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the uIP TCP/IP stack.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Implementation of the ARP Address Resolution Protocol.
|
||||
* \author Adam Dunkels <adam@dunkels.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup uip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup uiparp uIP Address Resolution Protocol
|
||||
* @{
|
||||
*
|
||||
* The Address Resolution Protocol ARP is used for mapping between IP
|
||||
* addresses and link level addresses such as the Ethernet MAC
|
||||
* addresses. ARP uses broadcast queries to ask for the link level
|
||||
* address of a known IP address and the host which is configured with
|
||||
* the IP address for which the query was meant, will respond with its
|
||||
* link level address.
|
||||
*
|
||||
* \note This ARP implementation only supports Ethernet.
|
||||
*/
|
||||
|
||||
#include "net/ipv4/uip_arp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct arp_hdr {
|
||||
struct uip_eth_hdr ethhdr;
|
||||
uint16_t hwtype;
|
||||
uint16_t protocol;
|
||||
uint8_t hwlen;
|
||||
uint8_t protolen;
|
||||
uint16_t opcode;
|
||||
struct uip_eth_addr shwaddr;
|
||||
uip_ipaddr_t sipaddr;
|
||||
struct uip_eth_addr dhwaddr;
|
||||
uip_ipaddr_t dipaddr;
|
||||
};
|
||||
|
||||
struct ethip_hdr {
|
||||
struct uip_eth_hdr ethhdr;
|
||||
/* IP header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
};
|
||||
|
||||
#define ARP_REQUEST 1
|
||||
#define ARP_REPLY 2
|
||||
|
||||
#define ARP_HWTYPE_ETH 1
|
||||
|
||||
struct arp_entry {
|
||||
uip_ipaddr_t ipaddr;
|
||||
struct uip_eth_addr ethaddr;
|
||||
uint8_t time;
|
||||
};
|
||||
|
||||
static const struct uip_eth_addr broadcast_ethaddr =
|
||||
{{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||
|
||||
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
|
||||
static uip_ipaddr_t ipaddr;
|
||||
static uint8_t i, c;
|
||||
|
||||
static uint8_t arptime;
|
||||
static uint8_t tmpage;
|
||||
|
||||
#define BUF ((struct arp_hdr *)&uip_buf[0])
|
||||
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initialize the ARP module.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_init(void)
|
||||
{
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
memset(&arp_table[i].ipaddr, 0, 4);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Periodic ARP processing function.
|
||||
*
|
||||
* This function performs periodic timer processing in the ARP module
|
||||
* and should be called at regular intervals. The recommended interval
|
||||
* is 10 seconds between the calls.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_timer(void)
|
||||
{
|
||||
struct arp_entry *tabptr;
|
||||
|
||||
++arptime;
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) &&
|
||||
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
|
||||
memset(&tabptr->ipaddr, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr)
|
||||
{
|
||||
register struct arp_entry *tabptr = arp_table;
|
||||
|
||||
/* Walk through the ARP mapping table and try to find an entry to
|
||||
update. If none is found, the IP -> MAC address mapping is
|
||||
inserted in the ARP table. */
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
|
||||
/* Only check those entries that are actually in use. */
|
||||
if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
|
||||
|
||||
/* Check if the source IP address of the incoming packet matches
|
||||
the IP address in this ARP table entry. */
|
||||
if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) {
|
||||
|
||||
/* An old entry found, update this and return. */
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
tabptr++;
|
||||
}
|
||||
|
||||
/* If we get here, no existing ARP table entry was found, so we
|
||||
create one. */
|
||||
|
||||
/* First, we try to find an unused entry in the ARP table. */
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no unused entry is found, we try to find the oldest entry and
|
||||
throw it away. */
|
||||
if(i == UIP_ARPTAB_SIZE) {
|
||||
tmpage = 0;
|
||||
c = 0;
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
if(arptime - tabptr->time > tmpage) {
|
||||
tmpage = arptime - tabptr->time;
|
||||
c = i;
|
||||
}
|
||||
}
|
||||
i = c;
|
||||
tabptr = &arp_table[i];
|
||||
}
|
||||
|
||||
/* Now, i is the ARP table entry which we will fill with the new
|
||||
information. */
|
||||
uip_ipaddr_copy(&tabptr->ipaddr, ipaddr);
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* ARP processing for incoming IP packets
|
||||
*
|
||||
* This function should be called by the device driver when an IP
|
||||
* packet has been received. The function will check if the address is
|
||||
* in the ARP cache, and if so the ARP cache entry will be
|
||||
* refreshed. If no ARP cache entry was found, a new one is created.
|
||||
*
|
||||
* This function expects an IP packet with a prepended Ethernet header
|
||||
* in the uip_buf[] buffer, and the length of the packet in the global
|
||||
* variable uip_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if 0
|
||||
void
|
||||
uip_arp_ipin(void)
|
||||
{
|
||||
uip_len -= sizeof(struct uip_eth_hdr);
|
||||
|
||||
/* Only insert/update an entry if the source IP address of the
|
||||
incoming IP packet comes from a host on the local network. */
|
||||
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
|
||||
(uip_hostaddr[0] & uip_netmask[0])) {
|
||||
return;
|
||||
}
|
||||
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
|
||||
(uip_hostaddr[1] & uip_netmask[1])) {
|
||||
return;
|
||||
}
|
||||
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* 0 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* ARP processing for incoming ARP packets.
|
||||
*
|
||||
* This function should be called by the device driver when an ARP
|
||||
* packet has been received. The function will act differently
|
||||
* depending on the ARP packet type: if it is a reply for a request
|
||||
* that we previously sent out, the ARP cache will be filled in with
|
||||
* the values from the ARP reply. If the incoming ARP packet is an ARP
|
||||
* request for our IP address, an ARP reply packet is created and put
|
||||
* into the uip_buf[] buffer.
|
||||
*
|
||||
* When the function returns, the value of the global variable uip_len
|
||||
* indicates whether the device driver should send out a packet or
|
||||
* not. If uip_len is zero, no packet should be sent. If uip_len is
|
||||
* non-zero, it contains the length of the outbound packet that is
|
||||
* present in the uip_buf[] buffer.
|
||||
*
|
||||
* This function expects an ARP packet with a prepended Ethernet
|
||||
* header in the uip_buf[] buffer, and the length of the packet in the
|
||||
* global variable uip_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_arpin(void)
|
||||
{
|
||||
|
||||
if(uip_len < sizeof(struct arp_hdr)) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
uip_clear_buf();
|
||||
|
||||
switch(BUF->opcode) {
|
||||
case UIP_HTONS(ARP_REQUEST):
|
||||
/* ARP request. If it asked for our address, we send out a
|
||||
reply. */
|
||||
/* if(BUF->dipaddr[0] == uip_hostaddr[0] &&
|
||||
BUF->dipaddr[1] == uip_hostaddr[1]) {*/
|
||||
PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n",
|
||||
BUF->dipaddr.u8[0], BUF->dipaddr.u8[1],
|
||||
BUF->dipaddr.u8[2], BUF->dipaddr.u8[3],
|
||||
uip_hostaddr.u8[0], uip_hostaddr.u8[1],
|
||||
uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
|
||||
if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
|
||||
/* First, we register the one who made the request in our ARP
|
||||
table, since it is likely that we will do more communication
|
||||
with this host in the future. */
|
||||
uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
|
||||
|
||||
BUF->opcode = UIP_HTONS(ARP_REPLY);
|
||||
|
||||
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
|
||||
memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6);
|
||||
memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6);
|
||||
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
|
||||
|
||||
uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr);
|
||||
uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
|
||||
|
||||
BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
|
||||
uip_len = sizeof(struct arp_hdr);
|
||||
}
|
||||
break;
|
||||
case UIP_HTONS(ARP_REPLY):
|
||||
/* ARP reply. We insert or update the ARP table if it was meant
|
||||
for us. */
|
||||
if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
|
||||
uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Prepend Ethernet header to an outbound IP packet and see if we need
|
||||
* to send out an ARP request.
|
||||
*
|
||||
* This function should be called before sending out an IP packet. The
|
||||
* function checks the destination IP address of the IP packet to see
|
||||
* what Ethernet MAC address that should be used as a destination MAC
|
||||
* address on the Ethernet.
|
||||
*
|
||||
* If the destination IP address is in the local network (determined
|
||||
* by logical ANDing of netmask and our IP address), the function
|
||||
* checks the ARP cache to see if an entry for the destination IP
|
||||
* address is found. If so, an Ethernet header is prepended and the
|
||||
* function returns. If no ARP cache entry is found for the
|
||||
* destination IP address, the packet in the uip_buf[] is replaced by
|
||||
* an ARP request packet for the IP address. The IP packet is dropped
|
||||
* and it is assumed that they higher level protocols (e.g., TCP)
|
||||
* eventually will retransmit the dropped packet.
|
||||
*
|
||||
* If the destination IP address is not on the local network, the IP
|
||||
* address of the default router is used instead.
|
||||
*
|
||||
* When the function returns, a packet is present in the uip_buf[]
|
||||
* buffer, and the length of the packet is in the global variable
|
||||
* uip_len.
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_arp_out(void)
|
||||
{
|
||||
struct arp_entry *tabptr = arp_table;
|
||||
|
||||
/* Find the destination IP address in the ARP table and construct
|
||||
the Ethernet header. If the destination IP addres isn't on the
|
||||
local network, we use the default router's IP address instead.
|
||||
|
||||
If not ARP table entry is found, we overwrite the original IP
|
||||
packet with an ARP request for the IP address. */
|
||||
|
||||
/* First check if destination is a local broadcast. */
|
||||
if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) {
|
||||
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
|
||||
} else if(IPBUF->destipaddr.u8[0] == 224) {
|
||||
/* Multicast. */
|
||||
IPBUF->ethhdr.dest.addr[0] = 0x01;
|
||||
IPBUF->ethhdr.dest.addr[1] = 0x00;
|
||||
IPBUF->ethhdr.dest.addr[2] = 0x5e;
|
||||
IPBUF->ethhdr.dest.addr[3] = IPBUF->destipaddr.u8[1];
|
||||
IPBUF->ethhdr.dest.addr[4] = IPBUF->destipaddr.u8[2];
|
||||
IPBUF->ethhdr.dest.addr[5] = IPBUF->destipaddr.u8[3];
|
||||
} else {
|
||||
/* Check if the destination address is on the local network. */
|
||||
if(!uip_ipaddr_maskcmp(&IPBUF->destipaddr, &uip_hostaddr, &uip_netmask)) {
|
||||
/* Destination address was not on the local network, so we need to
|
||||
use the default router's IP address instead of the destination
|
||||
address when determining the MAC address. */
|
||||
uip_ipaddr_copy(&ipaddr, &uip_draddr);
|
||||
} else {
|
||||
/* Else, we use the destination IP address. */
|
||||
uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr);
|
||||
}
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) {
|
||||
break;
|
||||
}
|
||||
tabptr++;
|
||||
}
|
||||
|
||||
if(i == UIP_ARPTAB_SIZE) {
|
||||
/* The destination address was not in our ARP table, so we
|
||||
overwrite the IP packet with an ARP request. */
|
||||
|
||||
memset(BUF->ethhdr.dest.addr, 0xff, 6);
|
||||
memset(BUF->dhwaddr.addr, 0x00, 6);
|
||||
memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6);
|
||||
memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6);
|
||||
|
||||
uip_ipaddr_copy(&BUF->dipaddr, &ipaddr);
|
||||
uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
|
||||
BUF->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */
|
||||
BUF->hwtype = UIP_HTONS(ARP_HWTYPE_ETH);
|
||||
BUF->protocol = UIP_HTONS(UIP_ETHTYPE_IP);
|
||||
BUF->hwlen = 6;
|
||||
BUF->protolen = 4;
|
||||
BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
uip_len = sizeof(struct arp_hdr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Build an ethernet header. */
|
||||
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
|
||||
}
|
||||
memcpy(IPBUF->ethhdr.src.addr, uip_lladdr.addr, 6);
|
||||
|
||||
IPBUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_IP);
|
||||
|
||||
uip_len += sizeof(struct uip_eth_hdr);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003, Adam Dunkels.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the uIP TCP/IP stack.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Macros and definitions for the ARP module.
|
||||
* \author Adam Dunkels <adam@dunkels.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup uip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup uiparp
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef UIP_ARP_H_
|
||||
#define UIP_ARP_H_
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The Ethernet header.
|
||||
*/
|
||||
struct uip_eth_hdr {
|
||||
struct uip_eth_addr dest;
|
||||
struct uip_eth_addr src;
|
||||
uint16_t type;
|
||||
};
|
||||
|
||||
#define UIP_ETHTYPE_ARP 0x0806
|
||||
#define UIP_ETHTYPE_IP 0x0800
|
||||
#define UIP_ETHTYPE_IPV6 0x86dd
|
||||
|
||||
|
||||
/* The uip_arp_init() function must be called before any of the other
|
||||
ARP functions. */
|
||||
void uip_arp_init(void);
|
||||
|
||||
/* The uip_arp_ipin() function should be called whenever an IP packet
|
||||
arrives from the Ethernet. This function refreshes the ARP table or
|
||||
inserts a new mapping if none exists. The function assumes that an
|
||||
IP packet with an Ethernet header is present in the uip_buf buffer
|
||||
and that the length of the packet is in the uip_len variable. */
|
||||
/*void uip_arp_ipin(void);*/
|
||||
#define uip_arp_ipin()
|
||||
|
||||
/* The uip_arp_arpin() should be called when an ARP packet is received
|
||||
by the Ethernet driver. This function also assumes that the
|
||||
Ethernet frame is present in the uip_buf buffer. When the
|
||||
uip_arp_arpin() function returns, the contents of the uip_buf
|
||||
buffer should be sent out on the Ethernet if the uip_len variable
|
||||
is > 0. */
|
||||
void uip_arp_arpin(void);
|
||||
|
||||
/* The uip_arp_out() function should be called when an IP packet
|
||||
should be sent out on the Ethernet. This function creates an
|
||||
Ethernet header before the IP header in the uip_buf buffer. The
|
||||
Ethernet header will have the correct Ethernet MAC destination
|
||||
address filled in if an ARP table entry for the destination IP
|
||||
address (or the IP address of the default router) is present. If no
|
||||
such table entry is found, the IP packet is overwritten with an ARP
|
||||
request and we rely on TCP to retransmit the packet that was
|
||||
overwritten. In any case, the uip_len variable holds the length of
|
||||
the Ethernet frame that should be transmitted. */
|
||||
void uip_arp_out(void);
|
||||
|
||||
/* The uip_arp_timer() function should be called every ten seconds. It
|
||||
is responsible for flushing old entries in the ARP table. */
|
||||
void uip_arp_timer(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \addtogroup uipconffunc
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Specifiy the Ethernet MAC address.
|
||||
*
|
||||
* The ARP code needs to know the MAC address of the Ethernet card in
|
||||
* order to be able to respond to ARP queries and to generate working
|
||||
* Ethernet headers.
|
||||
*
|
||||
* \note This macro only specifies the Ethernet MAC address to the ARP
|
||||
* code. It cannot be used to change the MAC address of the Ethernet
|
||||
* card.
|
||||
*
|
||||
* \param eaddr A pointer to a struct uip_eth_addr containing the
|
||||
* Ethernet MAC address of the Ethernet card.
|
||||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define uip_setethaddr(eaddr) do {uip_lladdr.addr[0] = eaddr.addr[0]; \
|
||||
uip_lladdr.addr[1] = eaddr.addr[1];\
|
||||
uip_lladdr.addr[2] = eaddr.addr[2];\
|
||||
uip_lladdr.addr[3] = eaddr.addr[3];\
|
||||
uip_lladdr.addr[4] = eaddr.addr[4];\
|
||||
uip_lladdr.addr[5] = eaddr.addr[5];} while(0)
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#endif /* UIP_ARP_H_ */
|
||||
/** @} */
|
@ -1179,13 +1179,9 @@ throughput degradation anyway.
|
||||
The maximum throughput when uIP acts as a receiver is not affected by
|
||||
the delayed acknowledgment throughput degradation.
|
||||
|
||||
\note The \ref uipsplit module implements a hack that overcomes the
|
||||
problems with the delayed acknowledgment throughput degradation.
|
||||
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
|
@ -1,122 +0,0 @@
|
||||
#include "descriptors.h"
|
||||
#include <cdc-acm/cdc.h>
|
||||
#include <contiki-conf.h>
|
||||
#include <usb-arch.h>
|
||||
|
||||
const struct usb_st_device_descriptor device_descriptor =
|
||||
{
|
||||
sizeof(struct usb_st_device_descriptor),
|
||||
DEVICE,
|
||||
0x0210,
|
||||
CDC,
|
||||
0,
|
||||
0,
|
||||
CTRL_EP_SIZE,
|
||||
0xffff,
|
||||
0xffff,
|
||||
0x0010,
|
||||
2,
|
||||
1,
|
||||
3,
|
||||
1
|
||||
};
|
||||
|
||||
const struct configuration_st {
|
||||
struct usb_st_configuration_descriptor configuration;
|
||||
struct usb_st_interface_descriptor comm;
|
||||
struct usb_cdc_header_func_descriptor header;
|
||||
struct usb_cdc_union_func_descriptor union_descr;
|
||||
struct usb_cdc_ethernet_func_descriptor ethernet;
|
||||
#if 1
|
||||
struct usb_st_endpoint_descriptor ep_notification;
|
||||
#endif
|
||||
struct usb_st_interface_descriptor data;
|
||||
struct usb_st_endpoint_descriptor ep_in;
|
||||
struct usb_st_endpoint_descriptor ep_out;
|
||||
} BYTE_ALIGNED configuration_block =
|
||||
{
|
||||
/* Configuration */
|
||||
{
|
||||
sizeof(configuration_block.configuration),
|
||||
CONFIGURATION,
|
||||
sizeof(configuration_block),
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
0x80,
|
||||
50
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.comm),
|
||||
INTERFACE,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
CDC,
|
||||
ETHERNET_NETWORKING_CONTROL_MODEL,
|
||||
0,
|
||||
0
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.header),
|
||||
CS_INTERFACE,
|
||||
CDC_FUNC_DESCR_HEADER,
|
||||
0x0110
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.union_descr),
|
||||
CS_INTERFACE,
|
||||
CDC_FUNC_DESCR_UNION,
|
||||
0, /* Master */
|
||||
{1} /* Slave */
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.ethernet),
|
||||
CS_INTERFACE,
|
||||
CDC_FUNC_DESCR_ETHERNET,
|
||||
4,
|
||||
0, /* No statistics */
|
||||
UIP_CONF_BUFFER_SIZE - UIP_CONF_LLH_LEN + 14,
|
||||
0, /* No multicast filters */
|
||||
0 /* No wake-up filters */
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.ep_notification),
|
||||
ENDPOINT,
|
||||
0x83,
|
||||
0x03,
|
||||
8,
|
||||
100
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.data),
|
||||
INTERFACE,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
CDC_DATA,
|
||||
0,
|
||||
TRANSPARENT_PROTOCOL,
|
||||
0
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.ep_in),
|
||||
ENDPOINT,
|
||||
0x81,
|
||||
0x02,
|
||||
64,
|
||||
0
|
||||
},
|
||||
{
|
||||
sizeof(configuration_block.ep_out),
|
||||
ENDPOINT,
|
||||
0x02,
|
||||
0x02,
|
||||
64,
|
||||
0
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const struct usb_st_configuration_descriptor const *configuration_head =
|
||||
(struct usb_st_configuration_descriptor const*)&configuration_block;
|
@ -1,43 +0,0 @@
|
||||
#include "string-descriptors.h"
|
||||
static const struct {
|
||||
struct usb_st_string_descriptor base;
|
||||
Uint16 chars[18];
|
||||
} string_descriptor_1_en= {{40, 3, {'U'}}, {
|
||||
'S', 'B', ' ', 'p', 's', 'e', 'u', 'd', 'o', ' ', 'e', 't', 'h', 'e', 'r', 'n', 'e', 't'}};
|
||||
static const struct {
|
||||
struct usb_st_string_descriptor base;
|
||||
Uint16 chars[8];
|
||||
} string_descriptor_2_all= {{20, 3, {'F'}}, {
|
||||
'l', 'u', 'f', 'f', 'w', 'a', 'r', 'e'}};
|
||||
static const struct {
|
||||
struct usb_st_string_descriptor base;
|
||||
Uint16 chars[2];
|
||||
} string_descriptor_3_all= {{8, 3, {'0'}}, {
|
||||
'.', '1'}};
|
||||
static const struct {
|
||||
struct usb_st_string_descriptor base;
|
||||
Uint16 chars[11];
|
||||
} string_descriptor_4_all= {{26, 3, {'0'}}, {
|
||||
'2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'}};
|
||||
static const struct usb_st_string_descriptor * string_table_en[] =
|
||||
{
|
||||
&string_descriptor_1_en.base,
|
||||
&string_descriptor_2_all.base,
|
||||
&string_descriptor_3_all.base,
|
||||
&string_descriptor_4_all.base,
|
||||
};
|
||||
static const struct {
|
||||
struct usb_st_language_descriptor base;
|
||||
Uint16 langs[0];
|
||||
} language_descriptor =
|
||||
{
|
||||
{4, 3, {0x0409}},
|
||||
{}};
|
||||
static const struct {
|
||||
struct usb_st_string_languages base;
|
||||
struct usb_st_string_language_map map[0];
|
||||
} string_languages_full={{1, 4, &language_descriptor.base,
|
||||
{{0x0409, string_table_en}}}, {
|
||||
}
|
||||
};
|
||||
const struct usb_st_string_languages * const string_languages = &string_languages_full.base;
|
@ -1,170 +0,0 @@
|
||||
#include <cdc-eth.h>
|
||||
#include <usb-api.h>
|
||||
#include <uip_arp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/ipv4/uip-fw.h>
|
||||
|
||||
#define DATA_IN 0x81
|
||||
#define DATA_OUT 0x02
|
||||
#define INTERRUPT_IN 0x83
|
||||
|
||||
|
||||
struct uip_eth_addr default_uip_ethaddr = {{0x02,0x00,0x00,0x00,0x00,0x02}};
|
||||
|
||||
static unsigned int
|
||||
handle_cdc_eth_requests()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct USBRequestHandler cdc_eth_request_handler =
|
||||
{
|
||||
0x21, 0x7f,
|
||||
0x00, 0x00,
|
||||
handle_cdc_eth_requests
|
||||
};
|
||||
|
||||
static struct USBRequestHandlerHook cdc_eth_request_hook =
|
||||
{
|
||||
NULL,
|
||||
&cdc_eth_request_handler
|
||||
};
|
||||
|
||||
static USBBuffer recv_buffer;
|
||||
static uint8_t recv_data[UIP_BUFSIZE];
|
||||
|
||||
static USBBuffer xmit_buffer[3];
|
||||
static uint8_t xmit_data[UIP_BUFSIZE];
|
||||
|
||||
static void
|
||||
init_recv_buffer()
|
||||
{
|
||||
recv_buffer.next = NULL;
|
||||
recv_buffer.data = recv_data;
|
||||
recv_buffer.left = UIP_BUFSIZE;
|
||||
recv_buffer.flags = USB_BUFFER_SHORT_END | USB_BUFFER_NOTIFY;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
usbeth_send(void)
|
||||
{
|
||||
if ((xmit_buffer[0].flags & USB_BUFFER_SUBMITTED)) return UIP_FW_DROPPED;
|
||||
uip_arp_out();
|
||||
memcpy(xmit_data, uip_buf, uip_len);
|
||||
xmit_buffer[0].next = NULL;
|
||||
xmit_buffer[0].left = uip_len;
|
||||
xmit_buffer[0].flags = USB_BUFFER_NOTIFY | USB_BUFFER_SHORT_END;
|
||||
xmit_buffer[0].data = xmit_data;
|
||||
|
||||
/* printf("usbeth_send: %d\n", uip_len); */
|
||||
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
|
||||
return UIP_FW_OK;
|
||||
}
|
||||
|
||||
static struct uip_fw_netif usbethif =
|
||||
{UIP_FW_NETIF(172,16,0,1, 255,255,255,255, usbeth_send)};
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
|
||||
PROCESS(usb_eth_process, "USB ethernet");
|
||||
|
||||
PROCESS_THREAD(usb_eth_process, ev , data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
usb_register_request_handler(&cdc_eth_request_hook);
|
||||
usb_setup();
|
||||
usb_set_ep_event_process(DATA_OUT, process_current);
|
||||
usb_set_global_event_process(process_current);
|
||||
uip_fw_default(&usbethif);
|
||||
uip_setethaddr(default_uip_ethaddr);
|
||||
uip_arp_init();
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
if (ev == PROCESS_EVENT_EXIT) break;
|
||||
if (ev == PROCESS_EVENT_POLL) {
|
||||
unsigned int events = usb_get_global_events();
|
||||
if (events) {
|
||||
if (events & USB_EVENT_CONFIG) {
|
||||
if (usb_get_current_configuration() != 0) {
|
||||
printf("Configured\n");
|
||||
usb_setup_bulk_endpoint(DATA_IN);
|
||||
usb_setup_bulk_endpoint(DATA_OUT);
|
||||
usb_setup_interrupt_endpoint(INTERRUPT_IN);
|
||||
init_recv_buffer();
|
||||
usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
|
||||
#if 0
|
||||
{
|
||||
static const uint8_t foo[4] = {0x12,0x34,0x56,0x78};
|
||||
xmit_buffer[0].next = NULL;
|
||||
xmit_buffer[0].left = sizeof(foo);
|
||||
xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
|
||||
xmit_buffer[0].data = &foo;
|
||||
|
||||
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
usb_disable_endpoint(DATA_IN);
|
||||
usb_disable_endpoint(DATA_OUT);
|
||||
usb_disable_endpoint(INTERRUPT_IN);
|
||||
}
|
||||
}
|
||||
}
|
||||
events = usb_get_ep_events(DATA_OUT);
|
||||
if (events & USB_EP_EVENT_NOTIFICATION) {
|
||||
uip_len = sizeof(recv_data) - recv_buffer.left;
|
||||
/* printf("Received: %d bytes\n", uip_len); */
|
||||
memcpy(uip_buf, recv_data, uip_len);
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
|
||||
uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src);
|
||||
tcpip_input();
|
||||
} else
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
|
||||
uip_len -= sizeof(struct uip_eth_hdr);
|
||||
tcpip_input();
|
||||
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
|
||||
uip_arp_arpin();
|
||||
/* If the above function invocation resulted in data that
|
||||
should be sent out on the network, the global variable
|
||||
uip_len is set to a value > 0. */
|
||||
if (uip_len > 0) {
|
||||
memcpy(xmit_data, uip_buf, uip_len);
|
||||
xmit_buffer[0].next = NULL;
|
||||
xmit_buffer[0].data = xmit_data;
|
||||
xmit_buffer[0].left = uip_len;
|
||||
xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
|
||||
|
||||
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
|
||||
/* printf("Sent: %d bytes\n", uip_len); */
|
||||
}
|
||||
}
|
||||
|
||||
init_recv_buffer();
|
||||
usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
void
|
||||
usb_cdc_eth_setup()
|
||||
{
|
||||
process_start(&usb_eth_process, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr)
|
||||
{
|
||||
usbethif.ipaddr = *addr;
|
||||
}
|
||||
|
||||
void
|
||||
dummy(uip_ipaddr_t *addr1, uip_ipaddr_t *addr2)
|
||||
{
|
||||
*addr1 = *addr2;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef CDC_ETH_H_NUI0ULFC7C__
|
||||
#define CDC_ETH_H_NUI0ULFC7C__
|
||||
|
||||
#include <net/ip/uip.h>
|
||||
|
||||
/* Should be called before usb_cdc_eth_setup */
|
||||
void
|
||||
usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr);
|
||||
|
||||
void
|
||||
usb_cdc_eth_setup();
|
||||
|
||||
#endif /* CDC_ETH_H_NUI0ULFC7C__ */
|
@ -1,450 +0,0 @@
|
||||
/* Adapted by Simon Berg from net/dhcpc.c */
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <uip_arp.h>
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "dhcps.h"
|
||||
|
||||
struct dhcp_msg {
|
||||
uint8_t op, htype, hlen, hops;
|
||||
uint8_t xid[4];
|
||||
uint16_t secs, flags;
|
||||
uint8_t ciaddr[4];
|
||||
uint8_t yiaddr[4];
|
||||
uint8_t siaddr[4];
|
||||
uint8_t giaddr[4];
|
||||
uint8_t chaddr[16];
|
||||
#ifndef UIP_CONF_DHCP_LIGHT
|
||||
uint8_t sname[64];
|
||||
uint8_t file[128];
|
||||
#endif
|
||||
uint8_t options[312];
|
||||
} CC_BYTE_ALIGNED;
|
||||
|
||||
#define BOOTP_BROADCAST 0x8000
|
||||
|
||||
#define DHCP_REQUEST 1
|
||||
#define DHCP_REPLY 2
|
||||
#define DHCP_HTYPE_ETHERNET 1
|
||||
#define DHCP_HLEN_ETHERNET 6
|
||||
#define DHCP_MSG_LEN 236
|
||||
|
||||
#define DHCPS_SERVER_PORT 67
|
||||
#define DHCPS_CLIENT_PORT 68
|
||||
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPDECLINE 4
|
||||
#define DHCPACK 5
|
||||
#define DHCPNAK 6
|
||||
#define DHCPRELEASE 7
|
||||
#define DHCPINFORM 8
|
||||
|
||||
#define DHCP_OPTION_SUBNET_MASK 1
|
||||
#define DHCP_OPTION_ROUTER 3
|
||||
#define DHCP_OPTION_DNS_SERVER 6
|
||||
#define DHCP_OPTION_REQ_IPADDR 50
|
||||
#define DHCP_OPTION_LEASE_TIME 51
|
||||
#define DHCP_OPTION_MSG_TYPE 53
|
||||
#define DHCP_OPTION_SERVER_ID 54
|
||||
#define DHCP_OPTION_REQ_LIST 55
|
||||
#define DHCP_OPTION_END 255
|
||||
|
||||
|
||||
|
||||
#define LEASE_FLAGS_ALLOCATED 0x01 /* Lease with an allocated address*/
|
||||
#define LEASE_FLAGS_VALID 0x02 /* Contains a valid but
|
||||
possibly outdated lease */
|
||||
|
||||
|
||||
static const struct dhcps_config *config;
|
||||
|
||||
|
||||
static uint8_t *
|
||||
find_option(uint8_t option)
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
uint8_t *optptr = &m->options[4];
|
||||
uint8_t *end = (uint8_t*)uip_appdata + uip_datalen();
|
||||
while(optptr < end && *optptr != DHCP_OPTION_END) {
|
||||
if(*optptr == option) {
|
||||
return optptr;
|
||||
}
|
||||
optptr += optptr[1] + 2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const uint8_t magic_cookie[4] = {99, 130, 83, 99};
|
||||
|
||||
static int
|
||||
check_cookie(void)
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
return memcmp(m->options, magic_cookie, 4) == 0;
|
||||
}
|
||||
|
||||
/* Finds any valid lease for a given MAC address */
|
||||
static struct dhcps_client_lease *
|
||||
lookup_lease_mac(const uint8_t *chaddr, uint8_t hlen)
|
||||
{
|
||||
struct dhcps_client_lease *lease = config->leases;
|
||||
struct dhcps_client_lease *end = config->leases + config->num_leases;
|
||||
while(lease != end) {
|
||||
if (lease->flags & LEASE_FLAGS_VALID
|
||||
&& memcmp(lease->chaddr, chaddr, hlen) == 0) {
|
||||
return lease;
|
||||
}
|
||||
lease++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dhcps_client_lease *
|
||||
lookup_lease_ip(const uip_ipaddr_t *ip)
|
||||
{
|
||||
struct dhcps_client_lease *lease = config->leases;
|
||||
struct dhcps_client_lease *end = config->leases + config->num_leases;
|
||||
while(lease != end) {
|
||||
if (uip_ipaddr_cmp(&lease->ipaddr, ip)) {
|
||||
return lease;
|
||||
}
|
||||
lease++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dhcps_client_lease *
|
||||
find_free_lease(void)
|
||||
{
|
||||
struct dhcps_client_lease *found = NULL;
|
||||
struct dhcps_client_lease *lease = config->leases;
|
||||
struct dhcps_client_lease *end = config->leases + config->num_leases;
|
||||
while(lease != end) {
|
||||
if (!(lease->flags & LEASE_FLAGS_VALID)) return lease;
|
||||
if (!(lease->flags & LEASE_FLAGS_ALLOCATED)) found = lease;
|
||||
lease++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
struct dhcps_client_lease *
|
||||
init_lease(struct dhcps_client_lease *lease,
|
||||
const uint8_t *chaddr, uint8_t hlen)
|
||||
{
|
||||
if (lease) {
|
||||
memcpy(lease->chaddr, chaddr, hlen);
|
||||
lease->flags = LEASE_FLAGS_VALID;
|
||||
}
|
||||
return lease;
|
||||
}
|
||||
|
||||
|
||||
static struct dhcps_client_lease *
|
||||
choose_address()
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
struct dhcps_client_lease *lease;
|
||||
lease = lookup_lease_mac(m->chaddr, m->hlen);
|
||||
if (lease) {
|
||||
return lease;
|
||||
}
|
||||
{
|
||||
uint8_t *opt;
|
||||
opt = find_option(DHCP_OPTION_REQ_IPADDR);
|
||||
if (opt && (lease = lookup_lease_ip((uip_ipaddr_t*)&opt[2]))
|
||||
&& !(lease->flags & LEASE_FLAGS_ALLOCATED)) {
|
||||
return init_lease(lease, m->chaddr,m->hlen);
|
||||
}
|
||||
}
|
||||
lease = find_free_lease();
|
||||
if (lease) {
|
||||
return init_lease(lease, m->chaddr,m->hlen);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct dhcps_client_lease *
|
||||
allocate_address()
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
struct dhcps_client_lease *lease;
|
||||
lease = lookup_lease_mac(m->chaddr, m->hlen);
|
||||
if (!lease) {
|
||||
uint8_t *opt;
|
||||
opt = find_option(DHCP_OPTION_REQ_IPADDR);
|
||||
if (!(opt && (lease = lookup_lease_ip((uip_ipaddr_t*)&opt[2]))
|
||||
&& !(lease->flags & LEASE_FLAGS_ALLOCATED))) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
lease->lease_end = clock_seconds()+config->default_lease_time;
|
||||
lease->flags |= LEASE_FLAGS_ALLOCATED;
|
||||
return lease;
|
||||
}
|
||||
|
||||
static struct dhcps_client_lease *
|
||||
release_address()
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
struct dhcps_client_lease *lease;
|
||||
lease = lookup_lease_mac(m->chaddr, m->hlen);
|
||||
if (!lease) {
|
||||
return NULL;
|
||||
}
|
||||
lease->flags &= ~LEASE_FLAGS_ALLOCATED;
|
||||
return lease;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t *
|
||||
add_msg_type(uint8_t *optptr, uint8_t type)
|
||||
{
|
||||
*optptr++ = DHCP_OPTION_MSG_TYPE;
|
||||
*optptr++ = 1;
|
||||
*optptr++ = type;
|
||||
return optptr;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t *
|
||||
add_server_id(uint8_t *optptr)
|
||||
{
|
||||
*optptr++ = DHCP_OPTION_SERVER_ID;
|
||||
*optptr++ = 4;
|
||||
memcpy(optptr, &uip_hostaddr, 4);
|
||||
return optptr + 4;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t *
|
||||
add_lease_time(uint8_t *optptr)
|
||||
{
|
||||
uint32_t lt;
|
||||
*optptr++ = DHCP_OPTION_LEASE_TIME;
|
||||
*optptr++ = 4;
|
||||
lt = UIP_HTONL(config->default_lease_time);
|
||||
memcpy(optptr, <, 4);
|
||||
return optptr + 4;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t *
|
||||
add_end(uint8_t *optptr)
|
||||
{
|
||||
*optptr++ = DHCP_OPTION_END;
|
||||
return optptr;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
add_config(uint8_t *optptr)
|
||||
{
|
||||
if (config->flags & DHCP_CONF_NETMASK) {
|
||||
*optptr++ = DHCP_OPTION_SUBNET_MASK;
|
||||
*optptr++ = 4;
|
||||
memcpy(optptr, &config->netmask, 4);
|
||||
optptr += 4;
|
||||
}
|
||||
if (config->flags & DHCP_CONF_DNSADDR) {
|
||||
*optptr++ = DHCP_OPTION_DNS_SERVER;
|
||||
*optptr++ = 4;
|
||||
memcpy(optptr, &config->dnsaddr, 4);
|
||||
optptr += 4;
|
||||
}
|
||||
if (config->flags & DHCP_CONF_DEFAULT_ROUTER) {
|
||||
*optptr++ = DHCP_OPTION_ROUTER;
|
||||
*optptr++ = 4;
|
||||
memcpy(optptr, &config->default_router, 4);
|
||||
optptr += 4;
|
||||
}
|
||||
return optptr;
|
||||
}
|
||||
|
||||
static void
|
||||
create_msg(CC_REGISTER_ARG struct dhcp_msg *m)
|
||||
{
|
||||
m->op = DHCP_REPLY;
|
||||
/* m->htype = DHCP_HTYPE_ETHERNET; */
|
||||
/* m->hlen = DHCP_HLEN_ETHERNET; */
|
||||
/* memcpy(m->chaddr, &uip_lladdr,DHCP_HLEN_ETHERNET); */
|
||||
m->hops = 0;
|
||||
m->secs = 0;
|
||||
memcpy(m->siaddr, &uip_hostaddr, 4);
|
||||
m->sname[0] = '\0';
|
||||
m->file[0] = '\0';
|
||||
memcpy(m->options, magic_cookie, sizeof(magic_cookie));
|
||||
}
|
||||
|
||||
static uip_ipaddr_t any_addr;
|
||||
static uip_ipaddr_t bcast_addr;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_offer(struct uip_udp_conn *conn, struct dhcps_client_lease *lease)
|
||||
{
|
||||
uint8_t *end;
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
create_msg(m);
|
||||
memcpy(&m->yiaddr, &lease->ipaddr,4);
|
||||
|
||||
end = add_msg_type(&m->options[4], DHCPOFFER);
|
||||
end = add_server_id(end);
|
||||
end = add_lease_time(end);
|
||||
end = add_config(end);
|
||||
end = add_end(end);
|
||||
uip_ipaddr_copy(&conn->ripaddr, &bcast_addr);
|
||||
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
|
||||
}
|
||||
|
||||
static void
|
||||
send_ack(struct uip_udp_conn *conn, struct dhcps_client_lease *lease)
|
||||
{
|
||||
uint8_t *end;
|
||||
uip_ipaddr_t ciaddr;
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
create_msg(m);
|
||||
memcpy(&m->yiaddr, &lease->ipaddr,4);
|
||||
|
||||
end = add_msg_type(&m->options[4], DHCPACK);
|
||||
end = add_server_id(end);
|
||||
end = add_lease_time(end);
|
||||
end = add_config(end);
|
||||
end = add_end(end);
|
||||
memcpy(&ciaddr, &lease->ipaddr,4);
|
||||
uip_ipaddr_copy(&conn->ripaddr, &bcast_addr);
|
||||
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
|
||||
printf("ACK\n");
|
||||
}
|
||||
static void
|
||||
send_nack(struct uip_udp_conn *conn)
|
||||
{
|
||||
uint8_t *end;
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
create_msg(m);
|
||||
memset(&m->yiaddr, 0, 4);
|
||||
|
||||
end = add_msg_type(&m->options[4], DHCPNAK);
|
||||
end = add_server_id(end);
|
||||
end = add_end(end);
|
||||
|
||||
uip_ipaddr_copy(&conn->ripaddr, &bcast_addr);
|
||||
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
|
||||
printf("NACK\n");
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(dhcp_server_process, "DHCP server");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
PROCESS_THREAD(dhcp_server_process, ev , data)
|
||||
{
|
||||
static struct uip_udp_conn *conn;
|
||||
static struct uip_udp_conn *send_conn;
|
||||
static struct dhcps_client_lease *lease;
|
||||
PROCESS_BEGIN();
|
||||
printf("DHCP server starting\n");
|
||||
uip_ipaddr(&any_addr, 0,0,0,0);
|
||||
uip_ipaddr(&bcast_addr, 255,255,255,255);
|
||||
conn = udp_new(&any_addr, UIP_HTONS(DHCPS_CLIENT_PORT), NULL);
|
||||
if (!conn) goto exit;
|
||||
send_conn = udp_new(&bcast_addr, UIP_HTONS(DHCPS_CLIENT_PORT), NULL);
|
||||
if (!send_conn) goto exit;
|
||||
|
||||
uip_udp_bind(conn, UIP_HTONS(DHCPS_SERVER_PORT));
|
||||
uip_udp_bind(send_conn, UIP_HTONS(DHCPS_SERVER_PORT));
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
if(ev == tcpip_event) {
|
||||
if (uip_newdata()) {
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
struct uip_udpip_hdr *header = (struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN];
|
||||
|
||||
if (m->op == DHCP_REQUEST && check_cookie() && m->hlen <= MAX_HLEN) {
|
||||
uint8_t *opt = find_option(DHCP_OPTION_MSG_TYPE);
|
||||
if (opt) {
|
||||
uint8_t mtype = opt[2];
|
||||
if (opt[2] == DHCPDISCOVER) {
|
||||
printf("Discover\n");
|
||||
lease = choose_address();
|
||||
if (lease) {
|
||||
lease->lease_end = clock_seconds()+config->default_lease_time;
|
||||
tcpip_poll_udp(send_conn);
|
||||
PROCESS_WAIT_EVENT_UNTIL(uip_poll());
|
||||
send_offer(conn,lease);
|
||||
}
|
||||
} else {
|
||||
uint8_t *opt = find_option(DHCP_OPTION_SERVER_ID);
|
||||
if (!opt || uip_ipaddr_cmp((uip_ipaddr_t*)&opt[2], &uip_hostaddr)) {
|
||||
if (mtype == DHCPREQUEST) {
|
||||
printf("Request\n");
|
||||
lease = allocate_address();
|
||||
tcpip_poll_udp(send_conn);
|
||||
PROCESS_WAIT_EVENT_UNTIL(uip_poll());
|
||||
if (!lease) {
|
||||
send_nack(send_conn);
|
||||
} else {
|
||||
send_ack(send_conn,lease);
|
||||
}
|
||||
} else if (mtype == DHCPRELEASE) {
|
||||
printf("Release\n");
|
||||
release_address();
|
||||
} else if (mtype == DHCPDECLINE) {
|
||||
printf("Decline\n");
|
||||
} else if (mtype == DHCPINFORM) {
|
||||
printf("Inform\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (uip_poll()) {
|
||||
|
||||
}
|
||||
}
|
||||
exit:
|
||||
printf("DHCP server exiting\n");
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
void
|
||||
dhcps_init(const struct dhcps_config *conf)
|
||||
{
|
||||
config = conf;
|
||||
process_start(&dhcp_server_process,NULL);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#ifndef DHCPS_H_6M2XYUGNTK__
|
||||
#define DHCPS_H_6M2XYUGNTK__
|
||||
#include "contiki-net.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_HLEN 6
|
||||
|
||||
struct dhcps_client_lease
|
||||
{
|
||||
uint8_t chaddr[MAX_HLEN];
|
||||
uip_ipaddr_t ipaddr;
|
||||
unsigned long lease_end;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct dhcps_config
|
||||
{
|
||||
unsigned long default_lease_time;
|
||||
uip_ipaddr_t netmask;
|
||||
uip_ipaddr_t dnsaddr;
|
||||
uip_ipaddr_t default_router;
|
||||
struct dhcps_client_lease *leases;
|
||||
uint8_t flags;
|
||||
uint8_t num_leases;
|
||||
};
|
||||
|
||||
#define DHCP_CONF_NETMASK 0x01
|
||||
#define DHCP_CONF_DNSADDR 0x02
|
||||
#define DHCP_CONF_DEFAULT_ROUTER 0x04
|
||||
|
||||
#define DHCP_INIT_LEASE(addr0, addr1, addr2, addr3) \
|
||||
{{0},{addr0, addr1, addr2, addr3},0,0}
|
||||
|
||||
/**
|
||||
* Start the DHCP server
|
||||
*
|
||||
* This function starts th DHCP server with the given configuration.
|
||||
* The flags field determines which options are actually sent to the
|
||||
* client
|
||||
*
|
||||
* \param conf Pointer to a configuration struct. The configuration is
|
||||
* not copied and should remain constant while the server is running.
|
||||
* The leases pointed to by the configuration must be in writable memory.
|
||||
**/
|
||||
void dhcps_init(const struct dhcps_config *conf);
|
||||
|
||||
#endif /* DHCPS_H_6M2XYUGNTK__ */
|
@ -1,6 +1,5 @@
|
||||
#include "dev/uart0.h"
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV4
|
||||
/* In case of IPv4: putchar() is defined by the SLIP driver */
|
||||
int
|
||||
putchar(int c)
|
||||
@ -8,4 +7,3 @@ putchar(int c)
|
||||
uart0_writeb((char)c);
|
||||
return c;
|
||||
}
|
||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "dev/uart1.h"
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV4
|
||||
/* In case of IPv4: putchar() is defined by the SLIP driver */
|
||||
int
|
||||
putchar(int c)
|
||||
@ -8,4 +7,3 @@ putchar(int c)
|
||||
uart1_writeb((char)c);
|
||||
return c;
|
||||
}
|
||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
||||
|
@ -132,9 +132,6 @@ uart0_writeb(unsigned char c)
|
||||
#endif /* TX_WITH_INTERRUPT */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if !NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */
|
||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initalize the RS232 port.
|
||||
*
|
||||
|
@ -97,9 +97,6 @@ uart1_writeb(unsigned char c)
|
||||
#endif /* TX_WITH_INTERRUPT */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if ! NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */
|
||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initalize the RS232 port.
|
||||
*
|
||||
|
@ -41,42 +41,6 @@ slip_arch_writeb(unsigned char c)
|
||||
{
|
||||
uart0_writeb(c);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* The serial line is used to transfer IP packets using slip. To make
|
||||
* it possible to send debug output over the same line we send debug
|
||||
* output as slip frames (i.e delimeted by SLIP_END).
|
||||
*
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
int
|
||||
putchar(int c)
|
||||
{
|
||||
#define SLIP_END 0300
|
||||
static char debug_frame = 0;
|
||||
|
||||
if (!debug_frame) { /* Start of debug output */
|
||||
slip_arch_writeb(SLIP_END);
|
||||
slip_arch_writeb('\r'); /* Type debug line == '\r' */
|
||||
debug_frame = 1;
|
||||
}
|
||||
|
||||
slip_arch_writeb((char)c);
|
||||
|
||||
/*
|
||||
* Line buffered output, a newline marks the end of debug output and
|
||||
* implicitly flushes debug output.
|
||||
*/
|
||||
if (c == '\n') {
|
||||
slip_arch_writeb(SLIP_END);
|
||||
debug_frame = 0;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initalize the RS232 port and the SLIP driver.
|
||||
*
|
||||
|
@ -42,41 +42,6 @@ slip_arch_writeb(unsigned char c)
|
||||
uart1_writeb(c);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* The serial line is used to transfer IP packets using slip. To make
|
||||
* it possible to send debug output over the same line we send debug
|
||||
* output as slip frames (i.e delimeted by SLIP_END).
|
||||
*
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
int
|
||||
putchar(int c)
|
||||
{
|
||||
#define SLIP_END 0300
|
||||
static char debug_frame = 0;
|
||||
|
||||
if (!debug_frame) { /* Start of debug output */
|
||||
slip_arch_writeb(SLIP_END);
|
||||
slip_arch_writeb('\r'); /* Type debug line == '\r' */
|
||||
debug_frame = 1;
|
||||
}
|
||||
|
||||
slip_arch_writeb((char)c);
|
||||
|
||||
/*
|
||||
* Line buffered output, a newline marks the end of debug output and
|
||||
* implicitly flushes debug output.
|
||||
*/
|
||||
if (c == '\n') {
|
||||
slip_arch_writeb(SLIP_END);
|
||||
debug_frame = 0;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Initalize the RS232 port and the SLIP driver.
|
||||
*
|
||||
|
@ -31,7 +31,6 @@
|
||||
*/
|
||||
|
||||
#include "contiki-net.h"
|
||||
#include "net/ipv4/uip-neighbor.h"
|
||||
#include "net/wpcap.h"
|
||||
|
||||
#include "net/wpcap-drv.h"
|
||||
|
@ -385,7 +385,6 @@ typedef uint32_t rtimer_clock_t;
|
||||
#endif
|
||||
|
||||
#define UIP_CONF_ND6_SEND_RA 0
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#define RPL_CONF_STATS 0
|
||||
|
||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||
@ -427,20 +426,6 @@ typedef uint32_t rtimer_clock_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 8
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* Network setup for non-IPv6 (rime). */
|
||||
#define UIP_CONF_IP_FORWARD 1
|
||||
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 108
|
||||
#endif
|
||||
|
||||
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 8
|
||||
#endif
|
||||
|
@ -79,11 +79,6 @@ MODULES += core/net core/net/mac core/net/mac/framer core/net/ip64-addr \
|
||||
|
||||
## Copied from Makefile.include, since Cooja overrides CFLAGS et al
|
||||
HAS_STACK = 0
|
||||
ifeq ($(CONTIKI_WITH_IPV4),1)
|
||||
HAS_STACK = 1
|
||||
CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1
|
||||
endif
|
||||
|
||||
ifeq ($(CONTIKI_WITH_RIME),1)
|
||||
HAS_STACK = 1
|
||||
CFLAGS += -DNETSTACK_CONF_WITH_RIME=1
|
||||
|
@ -49,12 +49,6 @@
|
||||
|
||||
#define w_memcpy memcpy
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#error NETSTACK_CONF_WITH_IPV4 && NETSTACK_CONF_WITH_IPV6: Bad configuration
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#ifdef NETSTACK_CONF_H
|
||||
|
||||
/* These header overrides the below default configuration */
|
||||
@ -75,16 +69,6 @@
|
||||
/* Radio setup */
|
||||
#define NETSTACK_CONF_RADIO cooja_radio_driver
|
||||
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
|
||||
/* Network setup for IPv4 */
|
||||
#define NETSTACK_CONF_NETWORK uip_driver
|
||||
#define NETSTACK_CONF_RADIO cooja_radio_driver
|
||||
#define UIP_CONF_IP_FORWARD 1
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#endif /* NETSTACK_CONF_H */
|
||||
@ -138,8 +122,7 @@
|
||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||
#define UIP_CONF_IPV6_CHECKS 1
|
||||
#define UIP_CONF_IPV6_REASSEMBLY 0
|
||||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#define UIP_CONF_NETIF_MAX_ADDRESSES
|
||||
|
||||
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
|
||||
#ifndef SICSLOWPAN_CONF_FRAG
|
||||
@ -203,8 +186,6 @@ typedef uint64_t rtimer_clock_t;
|
||||
#define UIP_CONF_PINGADDRCONF 0
|
||||
#define UIP_CONF_LOGGING 0
|
||||
|
||||
#define UIP_CONF_TCP_SPLIT 0
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
|
@ -76,25 +76,6 @@
|
||||
#define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
|
||||
#define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
|
||||
|
||||
#ifndef NETSTACK_CONF_WITH_IPV4
|
||||
#define NETSTACK_CONF_WITH_IPV4 0
|
||||
#endif
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
#include "dev/rs232.h"
|
||||
#include "dev/slip.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#include "net/uip-fw-drv.h"
|
||||
#include "net/ipv4/uip-over-mesh.h"
|
||||
static struct uip_fw_netif slipif =
|
||||
{UIP_FW_NETIF(0,0,0,0, 255,255,255,255, slip_send)};
|
||||
static struct uip_fw_netif meshif =
|
||||
{UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
|
||||
|
||||
#define UIP_OVER_MESH_CHANNEL 8
|
||||
static uint8_t is_gateway;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#ifndef NETSTACK_CONF_WITH_IPV6
|
||||
#define NETSTACK_CONF_WITH_IPV6 0
|
||||
#endif
|
||||
@ -137,22 +118,6 @@ long referenceVar;
|
||||
static struct cooja_mt_thread rtimer_thread;
|
||||
static struct cooja_mt_thread process_run_thread;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
static void
|
||||
set_gateway(void)
|
||||
{
|
||||
if(!is_gateway) {
|
||||
printf("%d.%d: making myself the IP network gateway.\n\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
|
||||
printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
|
||||
uip_ipaddr_to_quad(&uip_hostaddr));
|
||||
uip_over_mesh_set_gateway(&linkaddr_node_addr);
|
||||
uip_over_mesh_make_announced_gateway();
|
||||
is_gateway = 1;
|
||||
}
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
print_processes(struct process * const processes[])
|
||||
@ -243,35 +208,6 @@ contiki_init()
|
||||
printf("%s/%s\n",
|
||||
NETSTACK_NETWORK.name, NETSTACK_MAC.name);
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
/* IPv4 CONFIGURATION */
|
||||
{
|
||||
uip_ipaddr_t hostaddr, netmask;
|
||||
|
||||
process_start(&tcpip_process, NULL);
|
||||
process_start(&uip_fw_process, NULL);
|
||||
process_start(&slip_process, NULL);
|
||||
|
||||
slip_set_input_callback(set_gateway);
|
||||
|
||||
uip_init();
|
||||
uip_fw_init();
|
||||
uip_ipaddr(&hostaddr, 172,16,linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1]);
|
||||
uip_ipaddr(&netmask, 255,255,0,0);
|
||||
uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
|
||||
|
||||
uip_sethostaddr(&hostaddr);
|
||||
uip_setnetmask(&netmask);
|
||||
uip_over_mesh_set_net(&hostaddr, &netmask);
|
||||
uip_over_mesh_set_gateway_netif(&slipif);
|
||||
uip_fw_default(&meshif);
|
||||
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
|
||||
|
||||
rs232_set_input(slip_input_byte);
|
||||
printf("IPv4 address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr));
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 CONFIGURATION */
|
||||
{
|
||||
|
@ -44,13 +44,6 @@ char simIP[16];
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
|
||||
char simIPChanged;
|
||||
char simIP[4];
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
doInterfaceActionsBeforeTick(void)
|
||||
@ -60,20 +53,6 @@ doInterfaceActionsBeforeTick(void)
|
||||
/* check if IPv6 address should change */
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
|
||||
/* check if IPv4 address should change */
|
||||
/*
|
||||
if (simIPChanged) {
|
||||
uip_ipaddr_t hostaddr;
|
||||
uip_ipaddr(&hostaddr, simIP[0], simIP[1], simIP[2], simIP[3]);
|
||||
uip_sethostaddr(&hostaddr);
|
||||
simIPChanged = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
@ -1,418 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "radio-uip-uaodv.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/uaodv.h"
|
||||
#include "net/ipv4/uaodv-rt.h"
|
||||
#include "net/ipv4/uaodv-def.h"
|
||||
#include "lib/crc16.h"
|
||||
#include "list.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Packet buffer size and retransmission settings */
|
||||
#define MAX_BUFFERED_PACKETS 10
|
||||
#define MAX_RETRANSMISSIONS_RREP 16
|
||||
#define MAX_RETRANSMISSIONS_UNICAST 16
|
||||
|
||||
/* Forward packet (header) */
|
||||
#define FWD_ID "fWd:"
|
||||
#define FWD_ID_LENGTH 4
|
||||
#define FWD_NEXT_IP FWD_ID_LENGTH
|
||||
#define FWD_PACKET_LENGTH (FWD_NEXT_IP + 4)
|
||||
|
||||
/* Acknowledgement packet */
|
||||
#define ACK_ID "aCk"
|
||||
#define ACK_ID_LENGTH 3
|
||||
#define ACK_CRC ACK_ID_LENGTH
|
||||
#define ACK_PACKET_LENGTH (ACK_ID_LENGTH + 2)
|
||||
#define ACK_TIMEOUT (CLOCK_SECOND / 50) * (random_rand() % 100)
|
||||
|
||||
enum {
|
||||
EVENT_SEND_ACK
|
||||
};
|
||||
|
||||
struct buf_packet {
|
||||
struct buf_packet *next;
|
||||
uint8_t data[UIP_BUFSIZE];
|
||||
int len;
|
||||
uint8_t resends;
|
||||
uint8_t acked;
|
||||
uint8_t want_ack;
|
||||
uint16_t crc;
|
||||
uip_ipaddr_t finaldest;
|
||||
struct etimer etimer;
|
||||
};
|
||||
|
||||
LIST(buf_packet_list);
|
||||
MEMB(buf_packet_mem, struct buf_packet, MAX_BUFFERED_PACKETS);
|
||||
|
||||
PROCESS(radio_uip_process, "radio uIP uAODV process");
|
||||
|
||||
static const struct radio_driver *radio;
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void receiver(const struct radio_driver *d);
|
||||
uint8_t radio_uip_uaodv_send(void);
|
||||
void radio_uip_uaodv_init(const struct radio_driver *d);
|
||||
int radio_uip_handle_ack(uint8_t *buf, int len);
|
||||
uint16_t radio_uip_calc_crc(uint8_t *buf, int len);
|
||||
int radio_uip_buffer_outgoing_packet(uint8_t *buf, int len, uip_ipaddr_t *dest, int max_sends);
|
||||
int radio_uip_is_ack(uint8_t *buf, int len);
|
||||
int radio_uip_uaodv_add_header(uint8_t *buf, int len, uip_ipaddr_t *addr);
|
||||
int radio_uip_uaodv_remove_header(uint8_t *buf, int len);
|
||||
void radio_uip_uaodv_change_header(uint8_t *buf, int len, uip_ipaddr_t *addr);
|
||||
int radio_uip_uaodv_header_exists(uint8_t *buf, int len);
|
||||
int radio_uip_uaodv_is_broadcast(uip_ipaddr_t *addr);
|
||||
int radio_uip_uaodv_fwd_is_broadcast(uint8_t *buf, int len);
|
||||
int radio_uip_uaodv_fwd_is_me(uint8_t *buf, int len);
|
||||
int radio_uip_uaodv_dest_is_me(uint8_t *buf, int len);
|
||||
int radio_uip_uaodv_dest_port(uint8_t *buf, int len);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Main process - handles (re)transmissions and acks */
|
||||
PROCESS_THREAD(radio_uip_process, ev, data)
|
||||
{
|
||||
struct buf_packet *packet;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD();
|
||||
|
||||
if(ev == EVENT_SEND_ACK) {
|
||||
|
||||
/* Prepare and send ack for given 16-bit CRC */
|
||||
uint8_t ackPacket[ACK_PACKET_LENGTH];
|
||||
memcpy(ackPacket, ACK_ID, ACK_ID_LENGTH);
|
||||
ackPacket[ACK_CRC] = ((uint16_t) data >> 8);
|
||||
ackPacket[ACK_CRC+1] = ((uint16_t) data & 0xff);
|
||||
radio->send(ackPacket, ACK_PACKET_LENGTH);
|
||||
|
||||
} else if(ev == PROCESS_EVENT_TIMER) {
|
||||
/* Locate which packet acknowledgement timed out */
|
||||
for(packet = list_head(buf_packet_list);
|
||||
packet != NULL;
|
||||
packet = packet->next) {
|
||||
if (etimer_expired(&packet->etimer)) {
|
||||
|
||||
if (packet->acked) {
|
||||
/* Already acked packet, remove silently */
|
||||
list_remove(buf_packet_list, packet);
|
||||
memb_free(&buf_packet_mem, packet);
|
||||
|
||||
} else if (packet->resends > 0) {
|
||||
/* Resend packet */
|
||||
packet->resends--;
|
||||
etimer_set(&packet->etimer, ACK_TIMEOUT);
|
||||
|
||||
radio->send(packet->data, packet->len);
|
||||
|
||||
} else {
|
||||
/* Packet was resent maximum number of times */
|
||||
|
||||
/* If an ack was expected, flag destination to bad */
|
||||
if (packet->want_ack && !uip_ipaddr_cmp(&packet->finaldest, &uip_broadcast_addr)) {
|
||||
uaodv_bad_dest(&packet->finaldest);
|
||||
}
|
||||
|
||||
list_remove(buf_packet_list, packet);
|
||||
memb_free(&buf_packet_mem, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
receiver(const struct radio_driver *d)
|
||||
{
|
||||
uip_len = d->read(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
if (uip_len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Detect and handle acknowledgements */
|
||||
if (radio_uip_is_ack(&uip_buf[UIP_LLH_LEN], uip_len)) {
|
||||
radio_uip_handle_ack(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no uAODV header, receive as usual */
|
||||
if (!radio_uip_uaodv_header_exists(&uip_buf[UIP_LLH_LEN], uip_len)) {
|
||||
tcpip_input();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Drop packet unless we are the uAODV forwarder */
|
||||
if (!radio_uip_uaodv_fwd_is_me(&uip_buf[UIP_LLH_LEN], uip_len)) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
/* Send ack as soon as possible */
|
||||
uint16_t crc;
|
||||
crc = radio_uip_calc_crc(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
process_post(&radio_uip_process, EVENT_SEND_ACK, (void*) (uint32_t) crc);
|
||||
}
|
||||
|
||||
/* Strip header and receive packet */
|
||||
uip_len = radio_uip_uaodv_remove_header(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
tcpip_input();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
radio_uip_uaodv_send(void)
|
||||
{
|
||||
struct uaodv_rt_entry *route;
|
||||
|
||||
/* Transmit broadcast packets without header */
|
||||
if (radio_uip_uaodv_is_broadcast(&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr)) {
|
||||
return radio_uip_buffer_outgoing_packet(&uip_buf[UIP_LLH_LEN], uip_len, (void*) &uip_broadcast_addr, 1);
|
||||
}
|
||||
|
||||
/* Transmit uAODV packets with headers but without using route table */
|
||||
if (((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->proto == UIP_PROTO_UDP
|
||||
&& radio_uip_uaodv_dest_port(&uip_buf[UIP_LLH_LEN], uip_len) == UIP_HTONS(UAODV_UDPPORT)) {
|
||||
uip_ipaddr_t nexthop;
|
||||
memcpy(&nexthop, &((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr, 4);
|
||||
|
||||
uip_len = radio_uip_uaodv_add_header(
|
||||
&uip_buf[UIP_LLH_LEN],
|
||||
uip_len,
|
||||
&nexthop
|
||||
);
|
||||
|
||||
/* Buffer packet for persistent transmission */
|
||||
return radio_uip_buffer_outgoing_packet(
|
||||
&uip_buf[UIP_LLH_LEN],
|
||||
uip_len,
|
||||
&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN + FWD_PACKET_LENGTH])->destipaddr,
|
||||
MAX_RETRANSMISSIONS_RREP);
|
||||
}
|
||||
|
||||
/* Fetch already prepared uAODV route */
|
||||
route = uaodv_rt_lookup_any((&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr));
|
||||
if (route == NULL || route->is_bad) {
|
||||
|
||||
/* If we are forwarding, notify origin of this bad route */
|
||||
if (tcpip_is_forwarding) {
|
||||
uaodv_bad_dest((&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr));
|
||||
}
|
||||
|
||||
return UIP_FW_DROPPED;
|
||||
}
|
||||
|
||||
/* Add header and buffer packet for persistent transmission */
|
||||
uip_len = radio_uip_uaodv_add_header(&uip_buf[UIP_LLH_LEN], uip_len, uip_ds6_route_nexthop(route)); /* TODO Correct? */
|
||||
return radio_uip_buffer_outgoing_packet(
|
||||
&uip_buf[UIP_LLH_LEN],
|
||||
uip_len,
|
||||
&route->dest,
|
||||
MAX_RETRANSMISSIONS_UNICAST);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
radio_uip_uaodv_init(const struct radio_driver *d)
|
||||
{
|
||||
/* Prepare buffers and start main process */
|
||||
memb_init(&buf_packet_mem);
|
||||
list_init(buf_packet_list);
|
||||
process_start(&radio_uip_process, NULL);
|
||||
|
||||
radio = d;
|
||||
radio->set_receive_function(receiver);
|
||||
radio->on();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
radio_uip_calc_crc(uint8_t *buf, int len)
|
||||
{
|
||||
uint16_t crcacc = 0xffff;
|
||||
int counter;
|
||||
|
||||
/* TODO Not effective */
|
||||
for (counter = 0; counter < len; counter++) {
|
||||
crcacc = crc16_add(buf[counter], crcacc);
|
||||
}
|
||||
return crcacc;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_buffer_outgoing_packet(uint8_t *buf, int len, uip_ipaddr_t *dest, int max_sends)
|
||||
{
|
||||
struct buf_packet *packet;
|
||||
|
||||
uint16_t crc;
|
||||
|
||||
/* Calculate packet's unique CRC */
|
||||
crc = radio_uip_calc_crc(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
|
||||
/* Check if this packet is already being transmitted */
|
||||
for(packet = list_head(buf_packet_list);
|
||||
packet != NULL;
|
||||
packet = packet->next) {
|
||||
if (packet->crc == crc) {
|
||||
return UIP_FW_DROPPED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate storage memory */
|
||||
packet = (struct buf_packet *)memb_alloc(&buf_packet_mem);
|
||||
if (packet == NULL) {
|
||||
return UIP_FW_DROPPED;
|
||||
}
|
||||
|
||||
/* Prepare packet buffer */
|
||||
memcpy(packet->data, buf, len);
|
||||
packet->len = len;
|
||||
packet->resends = max_sends;
|
||||
packet->acked = 0;
|
||||
if (packet->resends > 1)
|
||||
packet->want_ack = 1;
|
||||
else
|
||||
packet->want_ack = 0;
|
||||
memcpy(&packet->finaldest, dest, 4);
|
||||
packet->crc = crc;
|
||||
|
||||
/* Set first transmission to as soon as possible */
|
||||
PROCESS_CONTEXT_BEGIN(&radio_uip_process);
|
||||
etimer_set(&packet->etimer, 0);
|
||||
PROCESS_CONTEXT_END(&radio_uip_process);
|
||||
|
||||
/* Add to buffered packets list */
|
||||
list_add(buf_packet_list, packet);
|
||||
|
||||
return UIP_FW_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_is_ack(uint8_t *buf, int len)
|
||||
{
|
||||
if (len != ACK_PACKET_LENGTH)
|
||||
return 0;
|
||||
|
||||
return memcmp(buf, ACK_ID, ACK_ID_LENGTH) == 0;
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_handle_ack(uint8_t *buf, int len)
|
||||
{
|
||||
struct buf_packet *packet;
|
||||
uint16_t ackCRC;
|
||||
|
||||
ackCRC = (uint16_t) (buf[ACK_CRC] << 8) + (uint16_t) (0xff&buf[ACK_CRC+1]);
|
||||
|
||||
/* Locate which packet was acknowledged */
|
||||
for(packet = list_head(buf_packet_list);
|
||||
packet != NULL;
|
||||
packet = packet->next) {
|
||||
if (packet->crc == ackCRC) {
|
||||
/* Signal packet has been acknowledged */
|
||||
packet->acked = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_add_header(uint8_t *buf, int len, uip_ipaddr_t *addr)
|
||||
{
|
||||
uint8_t tempbuf[len];
|
||||
memcpy(tempbuf, buf, len);
|
||||
memcpy(&buf[FWD_PACKET_LENGTH], tempbuf, len);
|
||||
memcpy(buf, FWD_ID, FWD_ID_LENGTH);
|
||||
memcpy(&buf[FWD_NEXT_IP], (char*)addr, 4);
|
||||
return FWD_PACKET_LENGTH + len;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_remove_header(uint8_t *buf, int len)
|
||||
{
|
||||
uint8_t tempbuf[len];
|
||||
memcpy(tempbuf, &buf[FWD_PACKET_LENGTH], len);
|
||||
memcpy(buf, tempbuf, len);
|
||||
return len - FWD_PACKET_LENGTH;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
radio_uip_uaodv_change_header(uint8_t *buf, int len, uip_ipaddr_t *addr)
|
||||
{
|
||||
memcpy(&buf[FWD_NEXT_IP], addr, 4);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_header_exists(uint8_t *buf, int len)
|
||||
{
|
||||
return !memcmp(buf, FWD_ID, FWD_ID_LENGTH);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_is_broadcast(uip_ipaddr_t *addr)
|
||||
{
|
||||
return uip_ipaddr_cmp(addr, &uip_broadcast_addr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_fwd_is_broadcast(uint8_t *buf, int len)
|
||||
{
|
||||
return radio_uip_uaodv_is_broadcast((uip_ipaddr_t*) &buf[FWD_NEXT_IP]);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_fwd_is_me(uint8_t *buf, int len)
|
||||
{
|
||||
return !memcmp(&buf[FWD_NEXT_IP], &uip_hostaddr, 4);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_dest_is_me(uint8_t *buf, int len)
|
||||
{
|
||||
return !memcmp((&((struct uip_udpip_hdr *)buf)->destipaddr), &uip_hostaddr, 4);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
radio_uip_uaodv_dest_port(uint8_t *buf, int len)
|
||||
{
|
||||
if (len < sizeof(struct uip_udpip_hdr))
|
||||
return -1;
|
||||
return (int) ((struct uip_udpip_hdr *)buf)->destport;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RADIO_UIP_UAODV_H_
|
||||
#define RADIO_UIP_UAODV_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/radio.h"
|
||||
|
||||
void
|
||||
radio_uip_uaodv_init(const struct radio_driver *d);
|
||||
|
||||
uint8_t
|
||||
radio_uip_uaodv_send(void);
|
||||
|
||||
#endif /* RADIO_UIP_UAODV_H_ */
|
@ -36,14 +36,6 @@
|
||||
|
||||
#define IMPLEMENT_PRINTF 1
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
/* uIP packets via SLIP */
|
||||
#include "uip.h"
|
||||
#define MAX_LOG_LENGTH (2*UIP_BUFSIZE)
|
||||
#else /* NETSTACK_CONF_WITH_IPV4 */
|
||||
#define MAX_LOG_LENGTH 1024
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#if MAX_LOG_LENGTH < 1024
|
||||
#undef MAX_LOG_LENGTH
|
||||
#define MAX_LOG_LENGTH 1024
|
||||
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "net/ip/uip.h"
|
||||
#include "dev/button-sensor.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#include "net/uaodv.h"
|
||||
#include "net/ipv4/uaodv-rt.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define COOJA_PORT 1234
|
||||
|
||||
PROCESS(test_uaodv_process, "uIP uAODV test process");
|
||||
AUTOSTART_PROCESSES(&uaodv_process, &test_uaodv_process);
|
||||
|
||||
static struct uip_udp_conn *out_conn;
|
||||
static struct uip_udp_conn *in_conn;
|
||||
/*---------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(test_uaodv_process, ev, data)
|
||||
{
|
||||
static uip_ipaddr_t addr;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("uIP uAODV test process started\n");
|
||||
|
||||
uip_ipaddr(&addr, 0,0,0,0);
|
||||
in_conn = udp_new(&addr, UIP_HTONS(0), NULL);
|
||||
uip_udp_bind(in_conn, UIP_HTONS(COOJA_PORT));
|
||||
|
||||
uip_ipaddr(&addr, 10,10,10,4);
|
||||
out_conn = udp_new(&addr, UIP_HTONS(COOJA_PORT), NULL);
|
||||
|
||||
button_sensor.configure(SENSORS_ACTIVE, 1);
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
|
||||
if(ev == sensors_event && data == &button_sensor) {
|
||||
struct uaodv_rt_entry *route;
|
||||
|
||||
uip_ipaddr(&addr, 10,10,10,4);
|
||||
route = uaodv_rt_lookup_any(&addr);
|
||||
if (route == NULL || route->is_bad) {
|
||||
printf("%d.%d.%d.%d: lookup %d.%d.%d.%d\n", uip_ipaddr_to_quad(&uip_hostaddr), uip_ipaddr_to_quad(&addr));
|
||||
uaodv_request_route_to(&addr);
|
||||
} else {
|
||||
printf("%d.%d.%d.%d: send to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&uip_hostaddr), uip_ipaddr_to_quad(&addr));
|
||||
tcpip_poll_udp(out_conn);
|
||||
PROCESS_WAIT_UNTIL(ev == tcpip_event && uip_poll());
|
||||
uip_send("cooyah COOJA", 12);
|
||||
}
|
||||
}
|
||||
|
||||
if(ev == tcpip_event && uip_newdata()) {
|
||||
((char*) uip_appdata)[uip_datalen()] = 0;
|
||||
printf("data received from %d.%d.%d.%d: %s\n",
|
||||
uip_ipaddr_to_quad(&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr),
|
||||
(char *)uip_appdata);
|
||||
leds_toggle(LEDS_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "contiki-net.h"
|
||||
#include "net/ipv4/uip-neighbor.h"
|
||||
#include "net/eth-proc.h"
|
||||
#include "eth.h"
|
||||
|
||||
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
||||
#define IPBUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
PROCESS(eth_process, "Ethernet");
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
static uint8_t
|
||||
output(const uip_lladdr_t *dest_mac)
|
||||
{
|
||||
if (dest_mac == NULL) {
|
||||
/* broadcast packet */
|
||||
memset(&BUF->dest, 0xFF, UIP_LLH_LEN);
|
||||
} else {
|
||||
memcpy(&BUF->dest, dest_mac, UIP_LLH_LEN);
|
||||
}
|
||||
memcpy(&BUF->src, uip_lladdr.addr, UIP_LLH_LEN);
|
||||
quarkX1000_eth_send();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static uint8_t
|
||||
output(void)
|
||||
{
|
||||
uip_arp_out();
|
||||
quarkX1000_eth_send();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
pollhandler(void)
|
||||
{
|
||||
process_poll(ð_process);
|
||||
quarkX1000_eth_poll(&uip_len);
|
||||
|
||||
if(uip_len > 0) {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
|
||||
tcpip_input();
|
||||
}
|
||||
#else
|
||||
if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
|
||||
uip_len -= sizeof(struct uip_eth_hdr);
|
||||
tcpip_input();
|
||||
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
|
||||
uip_arp_arpin();
|
||||
/* If the above function invocation resulted in data that
|
||||
should be sent out on the network, the global variable
|
||||
uip_len is set to a value > 0. */
|
||||
if(uip_len > 0) {
|
||||
quarkX1000_eth_send();
|
||||
}
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(eth_process, ev, data)
|
||||
{
|
||||
PROCESS_POLLHANDLER(pollhandler());
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
tcpip_set_outputfunc(output);
|
||||
|
||||
process_poll(ð_process);
|
||||
|
||||
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_GALILEO_NET_ETH_PROC_H_
|
||||
#define PLATFORM_GALILEO_NET_ETH_PROC_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
PROCESS_NAME(eth_process);
|
||||
|
||||
#endif /* PLATFORM_GALILEO_NET_ETH_PROC_H_ */
|
@ -62,12 +62,12 @@
|
||||
#define PROCESS_CONF_NUMEVENTS 8
|
||||
#define PROCESS_CONF_STATS 1
|
||||
|
||||
#if !defined NETSTACK_CONF_WITH_IPV6 && !defined NETSTACK_CONF_WITH_IPV4
|
||||
#if !defined NETSTACK_CONF_WITH_IPV6
|
||||
#define NETSTACK_CONF_WITH_IPV6 1
|
||||
#endif /* NETSTACK_CONF_ not defined */
|
||||
|
||||
/* Network setup for IP */
|
||||
#if NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
|
||||
#define LINKADDR_CONF_SIZE 8
|
||||
|
||||
@ -88,7 +88,7 @@
|
||||
#define QUEUEBUF_CONF_NUM 16
|
||||
#endif /* QUEUEBUF_CONF_NUM */
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 */
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* Network setup for IPv6 */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
@ -130,7 +130,6 @@
|
||||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
||||
#define UIP_CONF_ND6_MAX_PREFIXES 3
|
||||
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 1280
|
||||
#endif
|
||||
@ -166,8 +165,6 @@
|
||||
#define UIP_CONF_LOGGING 0
|
||||
#define LOG_CONF_ENABLED 0
|
||||
|
||||
#define UIP_CONF_TCP_SPLIT 0
|
||||
|
||||
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
|
||||
#define UIP_CONF_LOGGING 0
|
||||
|
||||
|
@ -92,24 +92,6 @@ unsigned char node_mac[8];
|
||||
* marks the end of the stack taking into account the used heap */
|
||||
extern uint32_t heap_location;
|
||||
|
||||
#ifndef NETSTACK_CONF_WITH_IPV4
|
||||
#define NETSTACK_CONF_WITH_IPV4 0
|
||||
#endif
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#include "net/ipv4/uip-fw-drv.h"
|
||||
#include "net/ipv4/uip-over-mesh.h"
|
||||
static struct uip_fw_netif slipif =
|
||||
{ UIP_FW_NETIF(192, 168, 1, 2, 255, 255, 255, 255, slip_send) };
|
||||
static struct uip_fw_netif meshif =
|
||||
{ UIP_FW_NETIF(172, 16, 0, 0, 255, 255, 0, 0, uip_over_mesh_send) };
|
||||
|
||||
#define UIP_OVER_MESH_CHANNEL 8
|
||||
static uint8_t is_gateway;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#ifdef EXPERIMENT_SETUP
|
||||
#include "experiment-setup.h"
|
||||
#endif
|
||||
@ -165,23 +147,6 @@ print_processes(struct process *const processes[])
|
||||
}
|
||||
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
static void
|
||||
set_gateway(void)
|
||||
{
|
||||
if(!is_gateway) {
|
||||
leds_on(LEDS_RED);
|
||||
printf("%d.%d: making myself the IP network gateway.\n\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
|
||||
printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
|
||||
uip_ipaddr_to_quad(&uip_hostaddr));
|
||||
uip_over_mesh_set_gateway(&linkaddr_node_addr);
|
||||
uip_over_mesh_make_announced_gateway();
|
||||
is_gateway = 1;
|
||||
}
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
start_autostart_processes()
|
||||
{
|
||||
@ -332,10 +297,6 @@ main(void)
|
||||
ctimer_init();
|
||||
uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
slip_arch_init(UART_BAUD_RATE);
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
/* check for reset source */
|
||||
if(bAHI_WatchdogResetEvent()) {
|
||||
PRINTF("Init: Watchdog timer has reset device!\r\n");
|
||||
@ -350,9 +311,6 @@ main(void)
|
||||
#else
|
||||
PRINTF(CONTIKI_VERSION_STRING " started with IPV6\n");
|
||||
#endif
|
||||
#elif NETSTACK_CONF_WITH_IPV4
|
||||
PRINTF(CONTIKI_VERSION_STRING " started with IPV4\n");
|
||||
#else
|
||||
PRINTF(CONTIKI_VERSION_STRING " started\n");
|
||||
#endif
|
||||
|
||||
@ -378,35 +336,6 @@ main(void)
|
||||
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
|
||||
#endif /* TIMESYNCH_CONF_ENABLED */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
process_start(&tcpip_process, NULL);
|
||||
process_start(&uip_fw_process, NULL); /* Start IP output */
|
||||
process_start(&slip_process, NULL);
|
||||
|
||||
slip_set_input_callback(set_gateway);
|
||||
|
||||
{
|
||||
uip_ipaddr_t hostaddr, netmask;
|
||||
|
||||
uip_init();
|
||||
|
||||
uip_ipaddr(&hostaddr, 172, 16,
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
|
||||
uip_ipaddr(&netmask, 255, 255, 0, 0);
|
||||
uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
|
||||
|
||||
uip_sethostaddr(&hostaddr);
|
||||
uip_setnetmask(&netmask);
|
||||
uip_over_mesh_set_net(&hostaddr, &netmask);
|
||||
/* uip_fw_register(&slipif);*/
|
||||
uip_over_mesh_set_gateway_netif(&slipif);
|
||||
uip_fw_default(&meshif);
|
||||
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
|
||||
PRINTF("uIP started with IP address %d.%d.%d.%d\n",
|
||||
uip_ipaddr_to_quad(&hostaddr));
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
watchdog_start();
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
|
@ -46,7 +46,6 @@
|
||||
|
||||
#include <MicroInt.h>
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
|
@ -70,7 +70,6 @@ typedef unsigned short uip_stats_t;
|
||||
#define UIP_CONF_BUFFER_SIZE 420
|
||||
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
||||
#define UIP_CONF_TCP 1
|
||||
#define UIP_CONF_TCP_SPLIT 0
|
||||
#define UIP_CONF_LOGGING 0
|
||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||
|
||||
@ -117,7 +116,6 @@ typedef unsigned short uip_stats_t;
|
||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
||||
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 240
|
||||
#endif
|
||||
|
@ -230,9 +230,7 @@ main(int argc, char **argv)
|
||||
|
||||
printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
|
||||
}
|
||||
#elif NETSTACK_CONF_WITH_IPV4
|
||||
process_start(&tcpip_process, NULL);
|
||||
#endif
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
serial_line_init();
|
||||
|
||||
|
@ -110,7 +110,6 @@
|
||||
/* ND and Routing */
|
||||
#define UIP_CONF_ROUTER 0 /**< BLE master role, which allows for routing, isn't supported. */
|
||||
#define UIP_CONF_ND6_SEND_NS 1
|
||||
#define UIP_CONF_IP_FORWARD 0 /**< No packet forwarding. */
|
||||
|
||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
||||
|
@ -442,7 +442,6 @@ typedef uint32_t rtimer_clock_t;
|
||||
#endif
|
||||
|
||||
#define UIP_CONF_ND6_SEND_RA 0
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#define RPL_CONF_STATS 0
|
||||
|
||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||
@ -484,20 +483,6 @@ typedef uint32_t rtimer_clock_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 8
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* Network setup for non-IPv6 (rime). */
|
||||
#define UIP_CONF_IP_FORWARD 1
|
||||
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 108
|
||||
#endif
|
||||
|
||||
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 8
|
||||
#endif
|
||||
|
@ -96,7 +96,6 @@
|
||||
#define UIP_CONF_IPV6_CHECKS 1
|
||||
#define UIP_CONF_IPV6_REASSEMBLY 0
|
||||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 240
|
||||
#endif
|
||||
@ -107,9 +106,7 @@
|
||||
#define SICSLOWPAN_CONF_MAXAGE 8
|
||||
#endif /* SICSLOWPAN_CONF_FRAG */
|
||||
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#define UIP_CONF_IP_FORWARD 1
|
||||
#define UIP_CONF_BUFFER_SIZE 108
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#define UIP_CONF_ICMP_DEST_UNREACH 1
|
||||
@ -133,8 +130,6 @@
|
||||
#define UIP_CONF_PINGADDRCONF 0
|
||||
#define UIP_CONF_LOGGING 0
|
||||
|
||||
#define UIP_CONF_TCP_SPLIT 0
|
||||
|
||||
#ifndef AES_128_CONF
|
||||
#define AES_128_CONF cc2420_aes_128_driver
|
||||
#endif /* AES_128_CONF */
|
||||
|
@ -71,26 +71,7 @@ static struct timer mgt_timer;
|
||||
#endif
|
||||
extern int msp430_dco_required;
|
||||
|
||||
#ifndef NETSTACK_CONF_WITH_IPV4
|
||||
#define NETSTACK_CONF_WITH_IPV4 0
|
||||
#endif
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#include "net/ipv4/uip-fw-drv.h"
|
||||
#include "net/ipv4/uip-over-mesh.h"
|
||||
static struct uip_fw_netif slipif =
|
||||
{UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
|
||||
static struct uip_fw_netif meshif =
|
||||
{UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#define UIP_OVER_MESH_CHANNEL 8
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
static uint8_t is_gateway;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
#ifdef EXPERIMENT_SETUP
|
||||
#include "experiment-setup.h"
|
||||
@ -170,23 +151,6 @@ print_processes(struct process * const processes[])
|
||||
putchar('\n');
|
||||
}
|
||||
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
static void
|
||||
set_gateway(void)
|
||||
{
|
||||
if(!is_gateway) {
|
||||
leds_on(LEDS_RED);
|
||||
PRINTF("%d.%d: making myself the IP network gateway.\n\n",
|
||||
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
|
||||
PRINTF("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
|
||||
uip_ipaddr_to_quad(&uip_hostaddr));
|
||||
uip_over_mesh_set_gateway(&linkaddr_node_addr);
|
||||
uip_over_mesh_make_announced_gateway();
|
||||
is_gateway = 1;
|
||||
}
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if WITH_TINYOS_AUTO_IDS
|
||||
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
|
||||
@ -255,10 +219,6 @@ main(int argc, char **argv)
|
||||
|
||||
ctimer_init();
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
slip_arch_init(BAUD2UBR(115200));
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
init_platform();
|
||||
|
||||
set_rime_addr();
|
||||
@ -345,7 +305,7 @@ main(int argc, char **argv)
|
||||
NETSTACK_MAC.name CC2420_CONF_CHANNEL);
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
uart1_set_input(serial_line_input_byte);
|
||||
serial_line_init();
|
||||
#endif
|
||||
@ -357,35 +317,6 @@ main(int argc, char **argv)
|
||||
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
|
||||
#endif /* TIMESYNCH_CONF_ENABLED */
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
process_start(&tcpip_process, NULL);
|
||||
process_start(&uip_fw_process, NULL); /* Start IP output */
|
||||
process_start(&slip_process, NULL);
|
||||
|
||||
slip_set_input_callback(set_gateway);
|
||||
|
||||
{
|
||||
uip_ipaddr_t hostaddr, netmask;
|
||||
|
||||
uip_init();
|
||||
|
||||
uip_ipaddr(&hostaddr, 172,16,
|
||||
linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1]);
|
||||
uip_ipaddr(&netmask, 255,255,0,0);
|
||||
uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
|
||||
|
||||
uip_sethostaddr(&hostaddr);
|
||||
uip_setnetmask(&netmask);
|
||||
uip_over_mesh_set_net(&hostaddr, &netmask);
|
||||
/* uip_fw_register(&slipif);*/
|
||||
uip_over_mesh_set_gateway_netif(&slipif);
|
||||
uip_fw_default(&meshif);
|
||||
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
|
||||
PRINTF("uIP started with IP address %d.%d.%d.%d\n",
|
||||
uip_ipaddr_to_quad(&hostaddr));
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
|
||||
watchdog_start();
|
||||
|
||||
#if !PROCESS_CONF_NO_PROCESS_NAMES
|
||||
|
@ -192,8 +192,6 @@
|
||||
#endif
|
||||
|
||||
#define UIP_CONF_ND6_SEND_RA 0
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#define RPL_CONF_STATS 0
|
||||
|
||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
||||
@ -215,12 +213,6 @@
|
||||
#define UIP_CONF_UDP 1
|
||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||
#define UIP_CONF_ICMP6 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* Network setup for non-IPv6 (rime). */
|
||||
#define UIP_CONF_IP_FORWARD 1
|
||||
|
||||
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/** @} */
|
||||
|
@ -473,7 +473,6 @@ typedef uint32_t rtimer_clock_t;
|
||||
#endif
|
||||
|
||||
#define UIP_CONF_ND6_SEND_RA 0
|
||||
#define UIP_CONF_IP_FORWARD 0
|
||||
#define RPL_CONF_STATS 0
|
||||
|
||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||
@ -517,20 +516,6 @@ typedef uint32_t rtimer_clock_t;
|
||||
|
||||
#define MAC_CONF_CHANNEL_CHECK_RATE 8
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 8
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* Network setup for non-IPv6 (rime). */
|
||||
#define UIP_CONF_IP_FORWARD 1
|
||||
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 108
|
||||
#endif
|
||||
|
||||
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
|
||||
|
||||
#ifndef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_CONF_NUM 8
|
||||
#endif
|
||||
|
@ -1,5 +0,0 @@
|
||||
all: tcp-server
|
||||
|
||||
CONTIKI=../..
|
||||
CONTIKI_WITH_IPV4 = 1
|
||||
include $(CONTIKI)/Makefile.include
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "contiki-net.h"
|
||||
#include "sys/cc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SERVER_PORT 80
|
||||
|
||||
static struct tcp_socket socket;
|
||||
|
||||
#define INPUTBUFSIZE 400
|
||||
static uint8_t inputbuf[INPUTBUFSIZE];
|
||||
|
||||
#define OUTPUTBUFSIZE 400
|
||||
static uint8_t outputbuf[OUTPUTBUFSIZE];
|
||||
|
||||
PROCESS(tcp_server_process, "TCP echo process");
|
||||
AUTOSTART_PROCESSES(&tcp_server_process);
|
||||
static uint8_t get_received;
|
||||
static int bytes_to_send;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
input(struct tcp_socket *s, void *ptr,
|
||||
const uint8_t *inputptr, int inputdatalen)
|
||||
{
|
||||
printf("input %d bytes '%s'\n", inputdatalen, inputptr);
|
||||
if(!get_received) {
|
||||
/* See if we have a full GET request in the buffer. */
|
||||
if(strncmp((char *)inputptr, "GET /", 5) == 0 &&
|
||||
atoi((char *)&inputptr[5]) != 0) {
|
||||
bytes_to_send = atoi((char *)&inputptr[5]);
|
||||
printf("bytes_to_send %d\n", bytes_to_send);
|
||||
return 0;
|
||||
}
|
||||
printf("inputptr '%.*s'\n", inputdatalen, inputptr);
|
||||
/* Return the number of data bytes we received, to keep them all
|
||||
in the buffer. */
|
||||
return inputdatalen;
|
||||
} else {
|
||||
/* Discard everything */
|
||||
return 0; /* all data consumed */
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
event(struct tcp_socket *s, void *ptr,
|
||||
tcp_socket_event_t ev)
|
||||
{
|
||||
printf("event %d\n", ev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(tcp_server_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
tcp_socket_register(&socket, NULL,
|
||||
inputbuf, sizeof(inputbuf),
|
||||
outputbuf, sizeof(outputbuf),
|
||||
input, event);
|
||||
tcp_socket_listen(&socket, SERVER_PORT);
|
||||
|
||||
printf("Listening on %d\n", SERVER_PORT);
|
||||
while(1) {
|
||||
PROCESS_PAUSE();
|
||||
|
||||
if(bytes_to_send > 0) {
|
||||
/* Send header */
|
||||
printf("sending header\n");
|
||||
tcp_socket_send_str(&socket, "HTTP/1.0 200 ok\r\nServer: Contiki tcp-socket example\r\n\r\n");
|
||||
|
||||
/* Send data */
|
||||
printf("sending data\n");
|
||||
while(bytes_to_send > 0) {
|
||||
PROCESS_PAUSE();
|
||||
int len, tosend;
|
||||
tosend = MIN(bytes_to_send, sizeof(outputbuf));
|
||||
len = tcp_socket_send(&socket, (uint8_t *)"", tosend);
|
||||
bytes_to_send -= len;
|
||||
}
|
||||
|
||||
tcp_socket_close(&socket);
|
||||
}
|
||||
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
@ -38,7 +38,6 @@
|
||||
#include "contiki.h"
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip-fw.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
@ -100,34 +99,6 @@ slip_set_tcpip_input_callback(void (*c)(void))
|
||||
tcpip_input_callback = c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV4
|
||||
uint8_t
|
||||
slip_send(void)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t *ptr;
|
||||
uint8_t c;
|
||||
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
ptr = &uip_buf[UIP_LLH_LEN];
|
||||
for(i = 0; i < uip_len; ++i) {
|
||||
c = *ptr++;
|
||||
if(c == SLIP_END) {
|
||||
slip_arch_writeb(SLIP_ESC);
|
||||
c = SLIP_ESC_END;
|
||||
} else if(c == SLIP_ESC) {
|
||||
slip_arch_writeb(SLIP_ESC);
|
||||
c = SLIP_ESC_ESC;
|
||||
}
|
||||
slip_arch_writeb(c);
|
||||
}
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
return UIP_FW_OK;
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
slip_write(const void *_ptr, int len)
|
||||
{
|
||||
@ -260,41 +231,6 @@ PROCESS_THREAD(slip_process, ev, data)
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) {
|
||||
char buf[8];
|
||||
memcpy(&buf[0], "=IPA", 4);
|
||||
memcpy(&buf[4], &uip_hostaddr, 4);
|
||||
if(input_callback) {
|
||||
input_callback();
|
||||
}
|
||||
slip_write(buf, 8);
|
||||
} else if(uip_len > 0
|
||||
&& uip_len == (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1])
|
||||
&& uip_ipchksum() == 0xffff) {
|
||||
#define IP_DF 0x40
|
||||
if(BUF->ipid[0] == 0 && BUF->ipid[1] == 0 && BUF->ipoffset[0] & IP_DF) {
|
||||
static uint16_t ip_id;
|
||||
uint16_t nid = ip_id++;
|
||||
BUF->ipid[0] = nid >> 8;
|
||||
BUF->ipid[1] = nid;
|
||||
nid = uip_htons(nid);
|
||||
nid = ~nid; /* negate */
|
||||
BUF->ipchksum += nid; /* add */
|
||||
if(BUF->ipchksum < nid) { /* 1-complement overflow? */
|
||||
BUF->ipchksum++;
|
||||
}
|
||||
}
|
||||
if(tcpip_input_callback) {
|
||||
tcpip_input_callback();
|
||||
} else {
|
||||
tcpip_input();
|
||||
}
|
||||
} else {
|
||||
uip_clear_buf();
|
||||
SLIP_STATISTICS(slip_ip_drop++);
|
||||
}
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(uip_len > 0) {
|
||||
if(tcpip_input_callback) {
|
||||
tcpip_input_callback();
|
||||
@ -302,7 +238,6 @@ PROCESS_THREAD(slip_process, ev, data)
|
||||
tcpip_input();
|
||||
}
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
|
@ -114,7 +114,6 @@ static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int);
|
||||
#define ARP_HWTYPE_ETH 1
|
||||
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv4/uip_arp.h"
|
||||
|
||||
struct ethip_hdr {
|
||||
struct uip_eth_hdr ethhdr;
|
||||
|
Loading…
Reference in New Issue
Block a user