added tun6 interface for native - removed old codebase for tap/tun/wpcap

This commit is contained in:
Joakim Eriksson 2017-10-01 21:40:51 +02:00
parent dd1dd89c11
commit 3091a9010a
29 changed files with 381 additions and 2295 deletions

View File

@ -30,6 +30,7 @@
*
* Author: Oliver Schmidt <ol.sc@web.de>
*
*
*/
#include "sys/mt.h"
@ -45,12 +46,7 @@
static void *main_fiber;
#elif defined(__linux) || defined(__APPLE__)
#ifdef __APPLE__
/* Avoid deprecated error on Darwin */
#define _XOPEN_SOURCE
#endif
#elif defined(__linux)
#include <stdlib.h>
#include <signal.h>
@ -63,6 +59,8 @@ struct mtarch_t {
static ucontext_t main_context;
static ucontext_t *running_context;
#elif defined(__APPLE)
/* No support for OS-X at the moment as swapcontext, etc are deprecated */
#endif /* _WIN32 || __CYGWIN__ || __linux */
@ -136,7 +134,7 @@ mtarch_yield(void)
SwitchToFiber(main_fiber);
#elif defined(__linux)
#elif defined(__linux)
swapcontext(running_context, &main_context);
@ -151,7 +149,6 @@ mtarch_exec(struct mtarch_thread *thread)
SwitchToFiber(thread->mt_thread);
#elif defined(__linux)
running_context = &((struct mtarch_t *)thread->mt_thread)->context;
swapcontext(&main_context, running_context);
running_context = NULL;
@ -167,7 +164,6 @@ mtarch_stop(struct mtarch_thread *thread)
DeleteFiber(thread->mt_thread);
#elif defined(linux) || defined(__linux)
free(thread->mt_thread);
#endif /* _WIN32 || __CYGWIN__ || __linux */

View File

@ -1,50 +0,0 @@
Contiki network I/O on Microsoft Windows (including the Cygwin environment) is
implemented based on the quite popular WinPcap library that is available at
[http://winpcap.org](http://winpcap.org).
Developing Contiki network applications most likely involves working with a
network protocol analyzer. Wireshark (formerly known as Ethereal) is a very
popular one that on Windows uses - and actually comes with - the WinPcap
libary. Wireshark is available at [http://wireshark.org](http://wireshark.org).
So with Wireshark installed Contiki network I/O doesn't need any additional
components.
On Windows every Contiki application has one obligatory comand line argument
that identifies the Windows network interface to be used by Contiki. While on
Unix those network interfaces are called i.e. '/dev/tap0' they have on Windows
names like
\Device\NPF_{F76B480A-1D31-4B3D-8002-C0EF49185737}
In order to avoid the necessity to enter such names on the command line instead
the IPv4 address used by Windows is entered to identify the network interface
to be used by Contiki. Please note that this IPv4 address is _NOT_ the IPv4
address to be used by Contiki !
Contiki network I/O on Windows uses the same MAC address used by Windows. This
approach often described as IP-Aliasing was primarily chosen because it avoids
putting the network interface into promiscuous mode. The major benefit of this
is the compatibility with WLAN interfaces - which mostly come with Windows
device drivers incapable of promiscuous mode.
The WinPcap library works fine with the 'Microsoft Loopback Adapter' so it's
easy to have a Contiki network application running on Windows communicate with
the local Windows instance for testing purposes - and monitor the communication
with Wireshark.
Windows Vista however tries to identify networks by the MAC address of the
default router. If that fails the network is defined as an 'Unidentified
Network' and thus classified as 'Public Network' resulting in very strict
firewall settings. As there's no default router for a loopback interface the
interface is always considered as a public network - which is kind of the
opposite of the actual situation ;-)
Instead of fiddling with the firewall settings for 'Public Networks' (or even
turning the firewall completely off) there's a clean solution which defines the
loopback interface as not a true network interface that connects to a network.
This results in generally deactivating both the network identification process
and the firewall for the loopback interface. The details are available in the
Microsoft TechNet Forums thread 'Vista Network Identification for Loopback
Adpater' that is currently available at
[link](http://social.technet.microsoft.com/Forums/windows/en-US/66b42761-1b8e-4302-9134-0bb685139f4e/vista-network-identification-for-loopback-adpater)

View File

@ -1,210 +0,0 @@
/*
* Copyright (c) 2013, Google
* 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.
*
* Author: Vladimir Pouzanov <farcaller@gmail.com>
*
*/
#include "contiki.h"
#include "contiki.h"
#if defined(linux) && NETSTACK_CONF_WITH_IPV6
#include "linuxradio-drv.h"
#include "net/packetbuf.h"
#include "net/netstack.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <linux/sockios.h>
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
static int sockfd = -1;
static char *sockbuf;
static int buflen;
#define MAX_PACKET_SIZE 256
static int
init(void)
{
sockbuf = malloc(MAX_PACKET_SIZE);
if(sockbuf == 0) {
return 1;
}
return 0;
}
static int
prepare(const void *payload, unsigned short payload_len)
{
if(payload_len > MAX_PACKET_SIZE) {
return 0;
}
memcpy(sockbuf, payload, payload_len);
buflen = payload_len;
return 0;
}
static int
transmit(unsigned short transmit_len)
{
int sent = 0;
sent = send(sockfd, sockbuf, buflen, 0);
if(sent < 0) {
perror("linuxradio send()");
return RADIO_TX_ERR;
}
buflen = 0;
return RADIO_TX_OK;
}
static int
my_send(const void *payload, unsigned short payload_len)
{
int ret = -1;
if(prepare(payload, payload_len)) {
return ret;
}
ret = transmit(payload_len);
return ret;
}
static int
my_read(void *buf, unsigned short buf_len)
{
return 0;
}
static int
channel_clear(void)
{
return 1;
}
static int
receiving_packet(void)
{
return 0;
}
static int
pending_packet(void)
{
return 0;
}
static int
set_fd(fd_set *rset, fd_set *wset)
{
FD_SET(sockfd, rset);
return 1;
}
static void
handle_fd(fd_set *rset, fd_set *wset)
{
if(FD_ISSET(sockfd, rset)) {
int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE);
buflen = bytes;
memcpy(packetbuf_dataptr(), sockbuf, bytes);
packetbuf_set_datalen(bytes);
NETSTACK_MAC.input();
}
}
static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd };
static int
on(void)
{
struct ifreq ifr;
int err;
struct sockaddr_ll sll;
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
if(sockfd < 0) {
perror("linuxradio socket()");
return 0;
} else {
strncpy((char *)ifr.ifr_name, NETSTACK_CONF_LINUXRADIO_DEV, IFNAMSIZ);
err = ioctl(sockfd, SIOCGIFINDEX, &ifr);
if(err == -1) {
perror("linuxradio ioctl()");
return 0;
}
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_IEEE802154);
if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
perror("linuxradio bind()");
return 0;
}
select_set_callback(sockfd, &linuxradio_sock_callback);
return 1;
}
}
static int
off(void)
{
close(sockfd);
sockfd = -1;
return 1;
}
const struct radio_driver linuxradio_driver =
{
init,
prepare,
transmit,
my_send,
my_read,
channel_clear,
receiving_packet,
pending_packet,
on,
off,
};
#endif

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2013, Google
* 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.
*
* Author: Vladimir Pouzanov <farcaller@gmail.com>
*
*/
#ifndef __LINUXRADIO_DRV_H__
#define __LINUXRADIO_DRV_H__
#include "dev/radio.h"
extern const struct radio_driver linuxradio_driver;
#endif

View File

@ -1,111 +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.
*
*/
#include "contiki-net.h"
#include "net/ipv6/uip.h"
#include "net/ipv6/uipopt.h"
#if NETSTACK_CONF_WITH_IPV6
#include "tapdev6.h"
#else
#include "tapdev.h"
#endif /* NETSTACK_CONF_WITH_IPV6 */
#include "tapdev-drv.h"
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
PROCESS(tapdev_process, "TAP driver");
/*---------------------------------------------------------------------------*/
#if !NETSTACK_CONF_WITH_IPV6
uint8_t
tapdev_output(void)
{
uip_arp_out();
tapdev_send();
return 0;
}
#endif
/*---------------------------------------------------------------------------*/
static void
pollhandler(void)
{
uip_len = tapdev_poll();
if(uip_len > 0) {
#if NETSTACK_CONF_WITH_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
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)) {
#if !NETSTACK_CONF_WITH_IPV6 //math
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) {
tapdev_send();
}
#endif
} else {
uip_clear_buf();
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(tapdev_process, ev, data)
{
PROCESS_POLLHANDLER(pollhandler());
PROCESS_BEGIN();
tapdev_init();
#if !NETSTACK_CONF_WITH_IPV6
tcpip_set_outputfunc(tapdev_output);
#else
tcpip_set_outputfunc(tapdev_send);
#endif
process_poll(&tapdev_process);
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
tapdev_exit();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -1,43 +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.
*
*/
#ifndef TAPDEV_DRV_H_
#define TAPDEV_DRV_H_
#include "contiki.h"
PROCESS_NAME(tapdev_process);
uint8_t tapdev_output(void);
int tapdev_fd(void);
#endif /* TAPDEV_DRV_H_ */

View File

@ -1,213 +0,0 @@
/*
* Copyright (c) 2001, 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "net/ipv6/uip.h"
#include "net/ipv6/uipopt.h"
#if !NETSTACK_CONF_WITH_IPV6
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/socket.h>
#ifdef linux
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#define DEVTAP "/dev/net/tun"
#else /* linux */
#define DEVTAP "/dev/tap0"
#endif /* linux */
#include "contiki-net.h"
#include "tapdev.h"
#define DROP 0
#if DROP
static int drop = 0;
#endif
static int fd;
static unsigned long lasttime;
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define DEBUG 0
#if DEBUG
#define PRINTF(...) fprintf(stderr, __VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
int
tapdev_fd(void)
{
return fd;
}
/*---------------------------------------------------------------------------*/
static void
remove_route(void)
{
char buf[1024];
int ret;
snprintf(buf, sizeof(buf), "route delete -net 172.18.0.0");
ret = system(buf);
fprintf(stderr, "ret %d\n", ret);
fprintf(stderr, "%s\n", buf);
}
/*---------------------------------------------------------------------------*/
void
tapdev_init(void)
{
char buf[1024];
int ret;
fd = open(DEVTAP, O_RDWR);
if(fd == -1) {
perror("tapdev: tapdev_init: open");
return;
}
#ifdef linux
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
perror("ioctl(TUNSETIFF)");
exit(1);
}
}
#endif /* Linux */
snprintf(buf, sizeof(buf), "ifconfig tap0 inet 172.18.0.1/16");
ret = system(buf);
fprintf(stderr, "ret %d\n", ret);
fprintf(stderr, "%s\n", buf);
#ifdef linux
/* route add for linux */
snprintf(buf, sizeof(buf), "route add -net 172.18.0.0/16 dev tap0");
#else /* linux */
/* route add for freebsd */
snprintf(buf, sizeof(buf), "route add -net 172.18.0.0/16 -iface tap0");
#endif /* linux */
ret = system(buf);
fprintf(stderr, "ret %d\n", ret);
fprintf(stderr, "%s\n", buf);
atexit(remove_route);
lasttime = 0;
}
/*---------------------------------------------------------------------------*/
uint16_t
tapdev_poll(void)
{
fd_set fdset;
struct timeval tv;
int ret;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fdset);
if(fd > 0) {
FD_SET(fd, &fdset);
}
ret = select(fd + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
return 0;
}
ret = read(fd, uip_buf, UIP_BUFSIZE);
PRINTF("tapdev_poll: read %d bytes\n", ret);
if(ret == -1) {
perror("tapdev_poll: read");
}
return ret;
}
/*---------------------------------------------------------------------------*/
void
tapdev_send(void)
{
int ret;
if(fd <= 0) {
return;
}
/* printf("tapdev_send: sending %d bytes\n", size);*/
/* check_checksum(uip_buf, size);*/
#if DROP
drop++;
if(drop % 8 == 7) {
fprintf(stderr, "Dropped an output packet!\n");
return;
}
#endif /* DROP */
PRINTF("tapdev_send: sending %d bytes\n", uip_len);
ret = write(fd, uip_buf, uip_len);
if(ret == -1) {
perror("tap_dev: tapdev_send: writev");
exit(1);
}
}
/*---------------------------------------------------------------------------*/
void
tapdev_exit(void)
{
}
/*---------------------------------------------------------------------------*/
#endif /* !NETSTACK_CONF_WITH_IPV6 */

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. 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.
*
*/
#ifndef TAPDEV_H_
#define TAPDEV_H_
void tapdev_init(void);
uint16_t tapdev_poll(void);
void tapdev_send(void);
void tapdev_exit(void);
#endif /* TAPDEV_H_ */

View File

@ -1,425 +0,0 @@
/*
* Copyright (c) 2001, 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "net/ipv6/uip.h"
#include "net/ipv6/uipopt.h"
#if NETSTACK_CONF_WITH_IPV6
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/socket.h>
#ifdef linux
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#define DEVTAP "/dev/net/tun"
#else /* linux */
#define DEVTAP "/dev/tap0"
#endif /* linux */
#ifdef __APPLE__
#include <net/if.h>
#include <netinet/in.h>
#include <netinet6/in6_var.h>
#include <netinet6/nd6.h> // ND6_INFINITE_LIFETIME
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <net/if_dl.h> // struct sockaddr_dl
#include <net/route.h> // AF_ROUTE things
#endif
#include "tapdev6.h"
#include "contiki-net.h"
#define DROP 0
#if DROP
static int drop = 0;
#endif
static int fd = -1;
static unsigned long lasttime;
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#endif
static void do_send(void);
uint8_t tapdev_send(const uip_lladdr_t *lladdr);
/*---------------------------------------------------------------------------*/
int
tapdev_fd(void)
{
return fd;
}
uint16_t
tapdev_poll(void)
{
fd_set fdset;
struct timeval tv;
int ret;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fdset);
if(fd > 0) {
FD_SET(fd, &fdset);
}
ret = select(fd + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
return 0;
}
ret = read(fd, uip_buf, UIP_BUFSIZE);
PRINTF("tapdev6: read %d bytes (max %d)\n", ret, UIP_BUFSIZE);
if(ret == -1) {
perror("tapdev_poll: read");
}
return ret;
}
/*---------------------------------------------------------------------------*/
#if defined(__APPLE__)
static int reqfd = -1, sfd = -1, interface_index;
static void
tapdev_init_darwin_routes(void)
{
struct stat st;
if(-1 == fstat(fd, &st)) {
perror("tapdev: fstat failed.");
exit(EXIT_FAILURE);
}
/************* Add address *************/
struct in6_aliasreq addreq6 = { };
reqfd = socket(AF_INET6, SOCK_DGRAM, 0);
if(-1 == fcntl(reqfd, F_SETFD, FD_CLOEXEC)) {
perror("tapdev: fcntl failed.");
exit(EXIT_FAILURE);
}
devname_r(st.st_rdev, S_IFCHR, addreq6.ifra_name,
sizeof(addreq6.ifra_name));
addreq6.ifra_addr.sin6_family = AF_INET6;
addreq6.ifra_addr.sin6_len = sizeof(addreq6.ifra_addr);
addreq6.ifra_addr.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFD00);
addreq6.ifra_addr.sin6_addr.__u6_addr.__u6_addr16[7] = UIP_HTONS(0x0001);
addreq6.ifra_prefixmask.sin6_family = AF_INET6;
addreq6.ifra_prefixmask.sin6_len = sizeof(addreq6.ifra_prefixmask);
addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[0] =
UIP_HTONS(0xFFFF);
addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[1] =
UIP_HTONS(0xFFFF);
addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[2] =
UIP_HTONS(0xFFFF);
addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[3] =
UIP_HTONS(0xFFFF);
addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
addreq6.ifra_lifetime.ia6t_expire = ND6_INFINITE_LIFETIME;
addreq6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME;
if(-1 == ioctl(reqfd, SIOCAIFADDR_IN6, &addreq6)) {
perror("tapdev: Uable to add address, call to ioctl failed.");
exit(EXIT_FAILURE);
}
/************* Add route *************/
int s = socket(AF_ROUTE, SOCK_RAW, AF_INET6);
if(s == -1) {
perror("tapdev: Unable to add route, call to socket() failed.");
// Failing to add the route is not fatal, so just return.
return;
}
sfd = s;
interface_index = if_nametoindex(devname(st.st_rdev, S_IFCHR));
PRINTF("tapdev: if_nametoindex(devname(st.st_rdev, S_IFCHR)) = %d\n",
interface_index);
PRINTF("tapdev: devname(st.st_rdev, S_IFCHR) = %s\n",
devname(st.st_rdev, S_IFCHR));
struct {
struct rt_msghdr hdr;
struct sockaddr_in6 dst;
struct sockaddr_dl gw;
struct sockaddr_in6 mask;
} msg = {};
msg.hdr.rtm_msglen = sizeof(msg);
msg.hdr.rtm_version = RTM_VERSION;
msg.hdr.rtm_type = RTM_ADD;
msg.hdr.rtm_index = interface_index;
msg.hdr.rtm_flags = RTF_UP | RTF_STATIC;
msg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
msg.hdr.rtm_pid = getpid();
msg.hdr.rtm_seq = 0;
msg.dst.sin6_family = AF_INET6;
msg.dst.sin6_len = sizeof(msg.dst);
msg.dst.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFD00);
msg.gw.sdl_family = AF_LINK;
msg.gw.sdl_len = sizeof(msg.gw);
msg.gw.sdl_index = interface_index;
msg.mask.sin6_family = AF_INET6;
msg.mask.sin6_len = sizeof(msg.mask);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFFFF);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[1] = UIP_HTONS(0xFFFF);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[2] = UIP_HTONS(0xFFFF);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[3] = UIP_HTONS(0xFFFF);
if(-1 == write(s, &msg, sizeof(msg))) {
perror("tapdev: Unable to add route, call to write() failed.");
// Failing to add the route is not fatal, so just return.
return;
}
}
/*---------------------------------------------------------------------------*/
static void
tapdev_cleanup_darwin_routes(void)
{
struct {
struct rt_msghdr hdr;
struct sockaddr_in6 dst;
struct sockaddr_dl gw;
struct sockaddr_in6 mask;
} msg = {};
msg.hdr.rtm_msglen = sizeof(msg);
msg.hdr.rtm_version = RTM_VERSION;
msg.hdr.rtm_type = RTM_DELETE;
msg.hdr.rtm_index = interface_index;
msg.hdr.rtm_flags = RTF_UP | RTF_STATIC;
msg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
msg.hdr.rtm_pid = getpid();
msg.hdr.rtm_seq = 0;
msg.dst.sin6_family = AF_INET6;
msg.dst.sin6_len = sizeof(msg.dst);
msg.dst.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFD00);
msg.gw.sdl_family = AF_LINK;
msg.gw.sdl_len = sizeof(msg.gw);
msg.gw.sdl_index = interface_index;
msg.mask.sin6_family = AF_INET6;
msg.mask.sin6_len = sizeof(msg.mask);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFFFF);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[1] = UIP_HTONS(0xFFFF);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[2] = UIP_HTONS(0xFFFF);
msg.mask.sin6_addr.__u6_addr.__u6_addr16[3] = UIP_HTONS(0xFFFF);
if(-1 == write(sfd, &msg, sizeof(msg))) {
perror("tapdev: Unable to delete route");
exit(EXIT_FAILURE);
}
close(reqfd);
close(sfd);
}
#endif // defined(__APPLE__)
/*---------------------------------------------------------------------------*/
void
tapdev_init(void)
{
char buf[1024];
fd = open(DEVTAP, O_RDWR);
if(fd == -1) {
perror("tapdev: tapdev_init: open");
return;
}
#ifdef linux
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
perror(buf);
exit(1);
}
}
#endif /* Linux */
#ifdef __APPLE__
tapdev_init_darwin_routes();
#endif
/* Linux (ubuntu)
snprintf(buf, sizeof(buf), "ip link set tap0 up");
system(buf);
PRINTF("%s\n", buf);
snprintf(buf, sizeof(buf), "ip -6 address add fc00::231/7 dev tap0");
system(buf);
PRINTF("%s\n", buf);
snprintf(buf, sizeof(buf), "ip -6 route add fc00::0/7 dev tap0");
system(buf);
PRINTF("%s\n", buf);
*/
/* freebsd */
snprintf(buf, sizeof(buf), "ifconfig tap0 up");
if(system(buf) == -1) {
perror("tapdev: system: ifconfig");
return;
}
printf("%s\n", buf);
/* */
lasttime = 0;
/* gdk_input_add(fd, GDK_INPUT_READ,
read_callback, NULL);*/
atexit(&tapdev_exit);
}
/*---------------------------------------------------------------------------*/
static void
do_send(void)
{
int ret;
if(fd <= 0) {
return;
}
PRINTF("tapdev_send: sending %d bytes\n", uip_len);
/* check_checksum(uip_buf, size);*/
#if DROP
drop++;
if(drop % 8 == 7) {
PRINTF("Dropped an output packet!\n");
return;
}
#endif /* DROP */
ret = write(fd, uip_buf, uip_len);
if(ret == -1) {
perror("tap_dev: tapdev_send: writev");
exit(1);
}
}
/*---------------------------------------------------------------------------*/
uint8_t
tapdev_send(const uip_lladdr_t *lladdr)
{
/*
* If L3 dest is multicast, build L2 multicast address
* as per RFC 2464 section 7
* else fill with th eaddrsess in argument
*/
if(lladdr == NULL) {
/* the dest must be multicast */
(&BUF->dest)->addr[0] = 0x33;
(&BUF->dest)->addr[1] = 0x33;
(&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12];
(&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13];
(&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14];
(&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15];
} else {
memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN);
}
memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN);
BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6); //math tmp
uip_len += sizeof(struct uip_eth_hdr);
do_send();
return 0;
}
/*---------------------------------------------------------------------------*/
void
tapdev_do_send(void)
{
do_send();
}
/*---------------------------------------------------------------------------*/
// math added function
void
tapdev_exit(void)
{
PRINTF("tapdev: Closing...\n");
#ifdef __APPLE__
tapdev_cleanup_darwin_routes();
#endif
close(fd);
}
/*---------------------------------------------------------------------------*/
#endif /* NETSTACK_CONF_WITH_IPV6 */

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Dunkels.
* 4. 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.
*
*
*/
#ifndef TAPDEV_H_
#define TAPDEV_H_
#include "contiki-net.h"
void tapdev_init(void);
uint8_t tapdev_send(const uip_lladdr_t *lladdr);
uint16_t tapdev_poll(void);
void tapdev_do_send(void);
void tapdev_exit(void); //math
#endif /* TAPDEV_H_ */

View File

@ -0,0 +1,303 @@
/*
* Copyright (c) 2011, 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.
*/
/**
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#define DEBUG DEBUG_NONE
#include "net/ip/uip-debug.h"
#ifdef linux
#include <linux/if.h>
#include <linux/if_tun.h>
#endif
#include <err.h>
#include "net/netstack.h"
#include "net/packetbuf.h"
static const char *config_ipaddr = "fd00::1/64";
/* Allocate some bytes in RAM and copy the string */
static char config_tundev[64] = "tun0";
#ifndef __CYGWIN__
static int tunfd;
static int set_fd(fd_set *rset, fd_set *wset);
static void handle_fd(fd_set *rset, fd_set *wset);
static const struct select_callback tun_select_callback = {
set_fd,
handle_fd
};
#endif /* __CYGWIN__ */
int ssystem(const char *fmt, ...)
__attribute__((__format__ (__printf__, 1, 2)));
int
ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
int
ssystem(const char *fmt, ...)
{
char cmd[128];
va_list ap;
va_start(ap, fmt);
vsnprintf(cmd, sizeof(cmd), fmt, ap);
va_end(ap);
printf("%s\n", cmd);
fflush(stdout);
return system(cmd);
}
/*---------------------------------------------------------------------------*/
void
cleanup(void)
{
ssystem("ifconfig %s down", config_tundev);
#ifndef linux
ssystem("sysctl -w net.ipv6.conf.all.forwarding=1");
#endif
ssystem("netstat -nr"
" | awk '{ if ($2 == \"%s\") print \"route delete -net \"$1; }'"
" | sh",
config_tundev);
}
/*---------------------------------------------------------------------------*/
void
sigcleanup(int signo)
{
fprintf(stderr, "signal %d\n", signo);
exit(0); /* exit(0) will call cleanup() */
}
/*---------------------------------------------------------------------------*/
void
ifconf(const char *tundev, const char *ipaddr)
{
#ifdef linux
ssystem("ifconfig %s inet `hostname` up", tundev);
ssystem("ifconfig %s add %s", tundev, ipaddr);
#elif defined(__APPLE__)
ssystem("ifconfig %s inet6 %s up", tundev, ipaddr);
ssystem("sysctl -w net.inet.ip.forwarding=1");
#else
ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr);
ssystem("sysctl -w net.inet.ip.forwarding=1");
#endif /* !linux */
/* Print the configuration to the console. */
ssystem("ifconfig %s\n", tundev);
}
/*---------------------------------------------------------------------------*/
int
devopen(const char *dev, int flags)
{
char t[32];
strcpy(t, "/dev/");
strncat(t, dev, sizeof(t) - 5);
return open(t, flags);
}
/*---------------------------------------------------------------------------*/
#ifdef linux
int
tun_alloc(char *dev)
{
struct ifreq ifr;
int fd, err;
PRINTF("Opening: %s\n", dev);
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
PRINTF("Failed to open tun device\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if(*dev != 0) {
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
PRINTF("Failed to do ioctl on fd\n");
close(fd);
return err;
}
PRINTF("Using '%s' vs '%s'\n", dev, ifr.ifr_name);
strncpy(dev, ifr.ifr_name, strlen(dev));
PRINTF("Using %s\n", dev);
return fd;
}
#else
int
tun_alloc(char *dev)
{
PRINTF("Opening: %s\n", dev);
return devopen(dev, O_RDWR);
}
#endif
#ifdef __CYGWIN__
/*wpcap process is used to connect to host interface */
void
tun_init()
{
setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */
}
#else
/*---------------------------------------------------------------------------*/
void
tun_init()
{
setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */
PRINTF("Initializing tun interface\n");
tunfd = tun_alloc(config_tundev);
if(tunfd == -1) err(1, "main: open");
PRINTF("Tun open:%d\n", tunfd);
select_set_callback(tunfd, &tun_select_callback);
fprintf(stderr, "opened %s device ``/dev/%s''\n",
"tun", config_tundev);
atexit(cleanup);
signal(SIGHUP, sigcleanup);
signal(SIGTERM, sigcleanup);
signal(SIGINT, sigcleanup);
ifconf(config_tundev, config_ipaddr);
}
/*---------------------------------------------------------------------------*/
static int
tun_output(uint8_t *data, int len)
{
/* fprintf(stderr, "*** Writing to tun...%d\n", len); */
if(write(tunfd, data, len) != len) {
err(1, "serial_to_tun: write");
return -1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
tun_input(unsigned char *data, int maxlen)
{
int size;
if((size = read(tunfd, data, maxlen)) == -1)
err(1, "tun_input: read");
return size;
}
/*---------------------------------------------------------------------------*/
static uint8_t
output(const linkaddr_t *localdest)
{
PRINTF("SUT: %u\n", uip_len);
if(uip_len > 0) {
return tun_output(&uip_buf[UIP_LLH_LEN], uip_len);
}
return 0;
}
/*---------------------------------------------------------------------------*/
/* tun and slip select callback */
/*---------------------------------------------------------------------------*/
static int
set_fd(fd_set *rset, fd_set *wset)
{
FD_SET(tunfd, rset);
return 1;
}
/*---------------------------------------------------------------------------*/
static void
handle_fd(fd_set *rset, fd_set *wset)
{
int size;
PRINTF("Tun6-handle FD\n");
if(FD_ISSET(tunfd, rset)) {
size = tun_input(&uip_buf[UIP_LLH_LEN], sizeof(uip_buf));
PRINTF("TUN data incoming read:%d\n", size);
uip_len = size;
tcpip_input();
}
}
#endif /* __CYGWIN_ */
void input(void)
{
/* should not happen */
PRINTF("Tun6 - input\n");
}
const struct network_driver tun6_net_driver ={
"tun6",
tun_init,
input,
output
};
/*---------------------------------------------------------------------------*/

View File

@ -1,179 +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 "contiki-net.h"
#include "net/wpcap.h"
#include "net/wpcap-drv.h"
#include <string.h>
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/* It is not particularly easy to install tun interfaces in Windows/cygwin, so wpcap
* is used instead. The ip4 or ip6 address of the interface to connect to is passed
* on the command line that invokes the minimal-net and native executables.
*
* The minimal-net border router uses wpcap to connect to both primary
* and fallback interfaces. It is passed two addresses, and the uip stack is compiled
* with space for the ethernet headers on both interfaces.
*
* However the native border router uses wpcap to connect to a fallback interface only.
* The primary interface is the serial connection to the slip radio, and the
* uip stack is compiled without space for ethernet headers.
* The following define adds or strips ethernet headers from the fallback interface.
* Since it is at present used only with the native border router, it is also used
* as a hack to bypass polling of the primary interface.
*
* SELECT_CALLBACK is defined in /examples/ipv6/native-border-router/project-conf.h
*/
#ifdef SELECT_CALLBACK
#define FALLBACK_HAS_ETHERNET_HEADERS 1
#endif
PROCESS(wpcap_process, "WinPcap driver");
/*---------------------------------------------------------------------------*/
#if !NETSTACK_CONF_WITH_IPV6
uint8_t
wpcap_output(void)
{
uip_arp_out();
wpcap_send();
return 0;
}
#endif /* !NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
static void
pollhandler(void)
{
#if !FALLBACK_HAS_ETHERNET_HEADERS //native br is fallback only
process_poll(&wpcap_process);
uip_len = wpcap_poll();
if(uip_len > 0) {
#if NETSTACK_CONF_WITH_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
// printf("wpcap poll calls tcpip");
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();
#if !NETSTACK_CONF_WITH_IPV6
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin(); //math
/* 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) {
wpcap_send();
}
#endif /* !NETSTACK_CONF_WITH_IPV6 */
} else {
uip_clear_buf();
}
}
#endif
#ifdef UIP_FALLBACK_INTERFACE
process_poll(&wpcap_process);
uip_len = wfall_poll();
if(uip_len > 0) {
#if FALLBACK_HAS_ETHERNET_HEADERS
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
//remove ethernet header and pass ipv6 packet to stack
uip_len-=14;
//{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(unsigned char*)(uip_buf+i));printf("\n");}
// memcpy(uip_buf, uip_buf+14, uip_len);
memcpy(&uip_buf[UIP_LLH_LEN], uip_buf+14, uip_len); //LLH_LEN is zero for native border router to slip radio
// CopyMemory(uip_buf, uip_buf+14, uip_len);
//{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
tcpip_input();
} else
goto bail;
#elif NETSTACK_CONF_WITH_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
tcpip_input();
} else
goto bail;
#endif /* NETSTACK_CONF_WITH_IPV6 */
if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
uip_len -= sizeof(struct uip_eth_hdr);
tcpip_input();
#if !NETSTACK_CONF_WITH_IPV6
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin(); //math
/* 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) {
wfall_send();
}
#endif /* !NETSTACK_CONF_WITH_IPV6 */
} else {
bail:
uip_clear_buf();
}
}
#endif
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(wpcap_process, ev, data)
{
PROCESS_POLLHANDLER(pollhandler());
PROCESS_BEGIN();
wpcap_init();
#if !NETSTACK_CONF_WITH_IPV6
tcpip_set_outputfunc(wpcap_output);
#else
#if !FALLBACK_HAS_ETHERNET_HEADERS
tcpip_set_outputfunc(wpcap_send);
#endif
#endif /* !NETSTACK_CONF_WITH_IPV6 */
process_poll(&wpcap_process);
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
wpcap_exit();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -1,42 +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 WPCAP_DRV_H_
#define WPCAP_DRV_H_
#include "contiki.h"
PROCESS_NAME(wpcap_process);
uint8_t wpcap_output(void);
#endif /* WPCAP_DRV_H_ */

View File

@ -1,807 +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.
*
* Author: Oliver Schmidt <ol.sc@web.de>
*
*/
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __CYGWIN__
#include <alloca.h>
#else /* __CYGWIN__ */
#include <malloc.h>
#endif /* __CYGWIN__ */
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#include "contiki-net.h"
#if LOG_CONF_ENABLED
void log_message(const char *part1, const char *part2);
#else /* LOG_CONF_ENABLED */
#define log_message(p1, p2)
#endif /* LOG_CONF_ENABLED */
#include "net/wpcap.h"
/* Handle native-border-router case where the fallback has ethernet headers.
* The command line args for native-border-router conflice with the passing
* of the interface addresses to connect to, so both must be hard coded.
* See comments in wpcap-drv.c
*/
#ifdef SELECT_CALLBACK
#define FALLBACK_HAS_ETHERNET_HEADERS 1
#endif
#if NETSTACK_CONF_WITH_IPV6
#include <ws2tcpip.h>
struct in6_addr addr6;
char addr6str[64];
/*---------------------------------------------------------------------------*/
uint8_t
issame_ip6addr(struct in6_addr addr1, struct in6_addr addr2)
{
return ((addr1.s6_addr32[0]==addr2.s6_addr32[0]) &&
(addr1.s6_addr32[1]==addr2.s6_addr32[1]) &&
(addr1.s6_addr32[2]==addr2.s6_addr32[2]) &&
(addr1.s6_addr32[3]==addr2.s6_addr32[3]) );
}
/*---------------------------------------------------------------------------*/
uint8_t
iszero_ip6addr(struct in6_addr addr)
{
return ((addr.s6_addr32[0]==0) &&
(addr.s6_addr32[1]==0) &&
(addr.s6_addr32[2]==0) &&
(addr.s6_addr32[3]==0) );
}
/*---------------------------------------------------------------------------*/
uint8_t
sprint_ip6addr(struct in6_addr addr, char * result)
{
unsigned char i = 0;
unsigned char zerocnt = 0;
unsigned char numprinted = 0;
char * starting = result;
*result++='[';
while (numprinted < 8) {
if ((addr.s6_addr16[i] == 0) && (zerocnt == 0)) {
while(addr.s6_addr16[zerocnt + i] == 0) zerocnt++;
if (zerocnt == 1) {
*result++ = '0';
numprinted++;
break;
}
i += zerocnt;
numprinted += zerocnt;
} else {
result += sprintf(result, "%x", (unsigned int) uip_ntohs(addr.s6_addr16[i]));
i++;
numprinted++;
}
if (numprinted != 8) *result++ = ':';
}
*result++=']';
*result=0;
return (result - starting);
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
#ifdef __CYGWIN__
__attribute__((dllimport)) extern char **__argv[];
#endif /* __CYGWIN__ */
struct pcap;
struct pcap_if {
struct pcap_if *next;
char *name;
char *description;
struct pcap_addr {
struct pcap_addr *next;
struct sockaddr *addr;
struct sockaddr *netmask;
struct sockaddr *broadaddr;
struct sockaddr *dstaddr;
} *addresses;
DWORD flags;
};
struct pcap_pkthdr {
struct timeval ts;
DWORD caplen;
DWORD len;
};
HMODULE wpcap;
static struct pcap *pcap;
/* uip_lladdr is defined in uip.c. It is not used in uip6.c.
* If needed for some purpose it can be defined here
*/
#if NETSTACK_CONF_WITH_IPV6
//struct uip_eth_addr uip_lladdr;
#endif
static int (* pcap_findalldevs)(struct pcap_if **, char *);
static struct pcap *(* pcap_open_live)(char *, int, int, int, char *);
static int (* pcap_next_ex)(struct pcap *, struct pcap_pkthdr **, unsigned char **);
static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int);
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#ifdef UIP_FALLBACK_INTERFACE
static struct pcap *pfall;
struct in_addr addrfall;
#if NETSTACK_CONF_WITH_IPV6
struct in_addr6 addrfall6;
#endif
/*---------------------------------------------------------------------------*/
static void
init(void)
{
/* Nothing to do here */
}
/*---------------------------------------------------------------------------*/
uint8_t wfall_send(const uip_lladdr_t *lladdr);
#if FALLBACK_HAS_ETHERNET_HEADERS
#undef IPBUF
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[14])
static uip_ipaddr_t last_sender;
#endif
static int
output(void)
{
#if FALLBACK_HAS_ETHERNET_HEADERS&&0
if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
/* Do not bounce packets back to fallback if the packet was received from it */
PRINTF("FUT: trapping pingpong");
return;
}
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
#endif
PRINTF("FUT: %u\n", uip_len);
return wfall_send(0);
}
const struct uip_fallback_interface rpl_interface = {
init, output
};
#endif
/*---------------------------------------------------------------------------*/
static void
error_exit(char *message)
{
printf("error_exit: %s", message);
exit(EXIT_FAILURE);
}
/*---------------------------------------------------------------------------*/
static void
set_ethaddr(struct in_addr addr)
{
PIP_ADAPTER_ADDRESSES adapters;
ULONG size = 0;
if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER,
NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) {
error_exit("error on access to adapter list size\n");
}
adapters = alloca(size);
if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER,
NULL, adapters, &size) != ERROR_SUCCESS) {
error_exit("error on access to adapter list\n");
}
while(adapters != NULL) {
char buffer[256];
WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1,
buffer, sizeof(buffer), NULL, NULL);
log_message("set_ethaddr: found adapter: ", buffer);
if(adapters->FirstUnicastAddress != NULL &&
adapters->FirstUnicastAddress->Address.lpSockaddr != NULL &&
adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET) {
struct in_addr adapter_addr;
adapter_addr = ((struct sockaddr_in *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin_addr;
log_message("set_ethaddr: with address: ", inet_ntoa(adapter_addr));
if(adapter_addr.s_addr == addr.s_addr) {
if(adapters->PhysicalAddressLength != 6) {
error_exit("ip addr specified on cmdline does not belong to an ethernet card\n");
}
wsprintf(buffer, "%02X-%02X-%02X-%02X-%02X-%02X",
adapters->PhysicalAddress[0], adapters->PhysicalAddress[1],
adapters->PhysicalAddress[2], adapters->PhysicalAddress[3],
adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]);
log_message("set_ethaddr: ethernetaddr: ", buffer);
#if NETSTACK_CONF_WITH_IPV6
// int i;for (i=0;i<6;i++) uip_lladdr.addr[i] = adapters->PhysicalAddress[i];
#else
uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress));
#endif
break;
}
}
adapters = adapters->Next;
}
if(adapters == NULL) {
error_exit("no adapter found with ip addr specified on cmdline\n");
}
}
#if NETSTACK_CONF_WITH_IPV6
/*---------------------------------------------------------------------------*/
static void
set_ethaddr6(struct in_addr6 addr)
{
PIP_ADAPTER_ADDRESSES adapters;
ULONG size = 0;
if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER,
NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) {
error_exit("error on access to adapter list size\n");
}
adapters = alloca(size);
if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER,
NULL, adapters, &size) != ERROR_SUCCESS) {
error_exit("error on access to adapter list\n");
}
while(adapters != NULL) {
char buffer[256];
WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1,
buffer, sizeof(buffer), NULL, NULL);
log_message("set_ethaddr: found adapter: ", buffer);
if(adapters->FirstUnicastAddress != NULL &&
adapters->FirstUnicastAddress->Address.lpSockaddr != NULL &&
adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET6) {
struct in_addr6 adapter_addr;
adapter_addr = ((struct sockaddr_in6 *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin6_addr;
sprint_ip6addr(adapter_addr, addr6str);
log_message("set_ethaddr: with ipv6 address: : ", addr6str);
if(issame_ip6addr(adapter_addr,addr6)) {
if(adapters->PhysicalAddressLength != 6) {
error_exit("ip addr specified on cmdline does not belong to an ethernet card\n");
}
wsprintf(buffer, "%02X-%02X-%02X-%02X-%02X-%02X",
adapters->PhysicalAddress[0], adapters->PhysicalAddress[1],
adapters->PhysicalAddress[2], adapters->PhysicalAddress[3],
adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]);
log_message("set_ethaddr: ethernetaddr: ", buffer);
#if NETSTACK_CONF_WITH_IPV6
// int i;for (i=0;i<6;i++) uip_lladdr.addr[i] = adapters->PhysicalAddress[i]; //does this need doing?
#else
uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress));
#endif
break;
}
}
adapters = adapters->Next;
}
if(adapters == NULL) {
error_exit("no adapter found with ip addr specified on cmdline\n");
}
}
#endif
/*---------------------------------------------------------------------------*/
static void
init_pcap(struct in_addr addr)
{
struct pcap_if *interfaces;
struct pcap_addr *paddr;
char error[256];
if(pcap_findalldevs(&interfaces, error) == -1) {
error_exit(error);
}
while(interfaces != NULL) {
log_message("init_pcap: found interface: ", interfaces->description);
if(interfaces->addresses != NULL) {
for(paddr = interfaces->addresses;
paddr != NULL;
paddr = paddr->next) {
if(paddr->addr != NULL && paddr->addr->sa_family == AF_INET) {
struct in_addr interface_addr;
interface_addr = ((struct sockaddr_in *)paddr->addr)->sin_addr;
log_message("init_pcap: with address: ", inet_ntoa(interface_addr));
if(interface_addr.s_addr == addr.s_addr) {
pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error);
if(pcap == NULL) {
error_exit(error);
}
#ifdef UIP_FALLBACK_INTERFACE
log_message("init_pcap: Opened as primary interface","");
#else
log_message("init_pcap: Opened as interface","");
#endif
// pcap_setdirection(PCAP_D_IN); //Not implemented in windows yet?
set_ethaddr(addr);
#ifdef UIP_FALLBACK_INTERFACE
}
if (pfall && pcap) return;
if(interface_addr.s_addr == addrfall.s_addr) {
pfall = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error);
if(pfall == NULL) {
error_exit(error);
}
log_message("init_pcap: Opened as fallback interface","");
if (pcap) return;
}
#else
return;
}
#endif
#if NETSTACK_CONF_WITH_IPV6
} else if(paddr->addr != NULL && paddr->addr->sa_family == AF_INET6) {
struct in6_addr interface_addr;
interface_addr = ((struct sockaddr_in6 *)paddr->addr)->sin6_addr;
sprint_ip6addr(interface_addr, addr6str);
log_message("init_pcap: with ipv6 address: ", addr6str);
if (issame_ip6addr(interface_addr, addr6)) {
pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error);
if(pcap == NULL) {
error_exit(error);
}
#ifdef UIP_FALLBACK_INTERFACE
log_message("init_pcap: Opened as primary interface","");
#endif
set_ethaddr6(addr6);
// pcap_setdirection(PCAP_D_IN); //Not implemented in windows yet?
#ifdef UIP_FALLBACK_INTERFACE
}
if (pfall && pcap) return; //exit when we have both interfaces
if (issame_ip6addr(interface_addr, addrfall6)) {
pfall = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error);
if(pfall == NULL) {
error_exit(error);
}
log_message("init_pcap: Opened as fallback interface","");
if (pcap) return;
}
#else
return;
}
#endif
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
}
}
interfaces = interfaces->next;
}
if(interfaces == NULL) {
error_exit("no interface found with specified ip address\n");
}
}
/*---------------------------------------------------------------------------*/
void
wpcap_init(void)
{
struct in_addr addr;
addr.s_addr = INADDR_NONE; //255.255.255.255
#ifdef UIP_FALLBACK_INTERFACE
addrfall.s_addr = INADDR_NONE;
#endif
/* Pick up possible ip addresses from command line */
#ifdef __CYGWIN__
if ((*__argv)[1]) {
addr.s_addr = inet_addr((*__argv)[1]);
#if NETSTACK_CONF_WITH_IPV6
uiplib_ipaddrconv((*__argv)[1],(uip_ipaddr_t*) &addr6.s6_addr);
#endif
#ifdef UIP_FALLBACK_INTERFACE
if ((*__argv)[2]) {
addrfall.s_addr = inet_addr((*__argv)[2]);
#if NETSTACK_CONF_WITH_IPV6
uiplib_ipaddrconv((*__argv)[2],(uip_ipaddr_t*) &addrfall6.s6_addr);
#endif
}
#endif
}
#else /* __CYGWIN__ */
/* VC++ build on win32 platform. Currently the platform has no ipv6 support */
addr.s_addr = inet_addr(__argv[1]);
#if NETSTACK_CONF_WITH_IPV6
if((__argv)[1])
uiplib_ipaddrconv((__argv)[1],(uip_ipaddr_t*) &addr6.s6_addr);
#endif
#ifdef UIP_FALLBACK_INTERFACE
addrfall.s_addr = inet_addr(__argv[2]);
#if NETSTACK_CONF_WITH_IPV6
if((__argv)[2])
uiplib_ipaddrconv((__argv)[2],(uip_ipaddr_t*) &addrfall6.s6_addr);
#endif
#endif
#endif /* __CYGWIN__ */
#if DEBUG
log_message("wpcap_init:Passed ipv4 ", inet_ntoa(addr));
sprint_ip6addr(addr6, addr6str);
log_message("wpcap_init:Passed ipv6 ", addr6str);
#ifdef UIP_FALLBACK_INTERFACE
log_message("wpcap_init:Passed fallback ipv4 ", inet_ntoa(addrfall));
sprint_ip6addr(addrfall6, addr6str);
log_message("wpcap_init:Passed fallback ipv6 ", addr6str);
#endif
#endif
/* Use build defaults if not enough addresses passed */
#if NETSTACK_CONF_WITH_IPV6
#ifdef UIP_FALLBACK_INTERFACE
if(addrfall.s_addr == INADDR_NONE) {
if(iszero_ip6addr(addrfall6)) {
#ifdef WPCAP_FALLBACK_ADDRESS
addrfall.s_addr = inet_addr(WPCAP_FALLBACK_ADDRESS);
// if(addrfall.s_addr == INADDR_NONE) { //use ipv6 if contiki-conf.h override
uiplib_ipaddrconv(WPCAP_FALLBACK_ADDRESS,(uip_ipaddr_t*) &addrfall6.s6_addr);
// }
#else
// addrfall.s_addr = inet_addr("10.2.10.10");
uiplib_ipaddrconv("bbbb::1",(uip_ipaddr_t*) &addrfall6.s6_addr);
#endif
}
}
#endif
if(addr.s_addr == INADDR_NONE) {
if(iszero_ip6addr(addr6)) {
#ifdef WPCAP_INTERFACE_ADDRESS
addr.s_addr = inet_addr(WPCAP_INTERFACE_ADDRESS);
// if(addr.s_addr == INADDR_NONE) {
uiplib_ipaddrconv(WPCAP_INTERFACE_ADDRESS,(uip_ipaddr_t*) &addr6.s6_addr);
// }
#else
addr.s_addr = inet_addr("10.10.10.10"); //prefer ipv4 default for legacy compatibility
// uiplib_ipaddrconv("fd00::1",(uip_ipaddr_t*) &addr6.s6_addr);
#endif
#ifdef UIP_FALLBACK_INTERFACE
log_message("usage: <program> <ip addr of interface> <ip addr of fallback>\n","");
if(addr.s_addr != INADDR_NONE) {
log_message("-->I'll try interface address ", inet_ntoa(addr));
} else {
sprint_ip6addr(addr6, addr6str);
log_message("-->I'll try interface address ", addr6str);
}
if(addrfall.s_addr != INADDR_NONE) {
log_message("--> and fallback address ", inet_ntoa(addrfall));
} else {
sprint_ip6addr(addrfall6, addr6str);
log_message("--> and fallback address ", addr6str);
}
#else
if(addr.s_addr != INADDR_NONE) {
log_message("usage: <program> <ip addr of ethernet card to share>\n-->I'll try guessing ", inet_ntoa(addr));
} else {
sprint_ip6addr(addr6, addr6str);
log_message("usage: <program> <ip addr of ethernet card to share>\n-->I'll try guessing ", addr6str);
}
#endif
}
}
#else /* ip4 build */
if(addr.s_addr == INADDR_NONE) {
#ifdef WPCAP_INTERFACE_ADDRESS
addr.s_addr = inet_addr(WPCAP_INTERFACE_ADDRESS);
#else
addr.s_addr = inet_addr("10.10.10.10");
#endif
log_message("usage: <program> <ip addr of ethernet card to share>\n-->I'll try guessing ", inet_ntoa(addr));
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
#if DEBUG
log_message("wpcap_init:Using ipv4 ", inet_ntoa(addr));
sprint_ip6addr(addr6, addr6str);
log_message("wpcap_init:Using ipv6 ", addr6str);
#ifdef UIP_FALLBACK_INTERFACE
log_message("wpcap_init:Using fallback ipv4 ", inet_ntoa(addrfall));
sprint_ip6addr(addrfall6, addr6str);
log_message("wpcap_init:Using fallback ipv6 ", addr6str);
#endif
#endif
// log_message("wpcap_init:cmdline address: ", inet_ntoa(addr));
wpcap = LoadLibrary("wpcap.dll");
pcap_findalldevs = (int (*)(struct pcap_if **, char *))
GetProcAddress(wpcap, "pcap_findalldevs");
pcap_open_live = (struct pcap *(*)(char *, int, int, int, char *))
GetProcAddress(wpcap, "pcap_open_live");
pcap_next_ex = (int (*)(struct pcap *, struct pcap_pkthdr **, unsigned char **))
GetProcAddress(wpcap, "pcap_next_ex");
pcap_sendpacket = (int (*)(struct pcap *, unsigned char *, int))
GetProcAddress(wpcap, "pcap_sendpacket");
if(pcap_findalldevs == NULL || pcap_open_live == NULL ||
pcap_next_ex == NULL || pcap_sendpacket == NULL) {
error_exit("error on access to winpcap library\n");
}
init_pcap(addr);
}
/*---------------------------------------------------------------------------*/
uint16_t
wpcap_poll(void)
{
struct pcap_pkthdr *packet_header;
unsigned char *packet;
switch(pcap_next_ex(pcap, &packet_header, &packet)) {
case -1:
error_exit("error on poll\n");
case 0:
return 0;
}
#if NETSTACK_CONF_WITH_IPV6
/* Since pcap_setdirection(PCAP_D_IN) is not implemented in winpcap all outgoing packets
* will be echoed back. The stack will ignore any packets not addressed to it, but initial
* ipv6 neighbor solicitations are addressed to everyone and the echoed NS sent on startup
* would be processed as a conflicting NS race which would cause a stack shutdown.
* So discard all packets with our source address (packet starts destaddr, srcaddr, ...)
*
*/
int i;
for (i=0;i<UIP_LLADDR_LEN;i++) if (*(packet+UIP_LLADDR_LEN+i)!=uip_lladdr.addr[i]) break;
if (i==UIP_LLADDR_LEN) {
PRINTF("SIN: Discarding echoed packet\n");
return 0;
}
/* To implement multihop, ignore packets to us from specified source macs
*/
// printf("ethtype=%x %x",*(packet+2*UIP_LLADDR_LEN),*(packet+2*UIP_LLADDR_LEN+1));
// printf("hopcount=%u",*(packet+21));
#if 0
if (0
// || (*(packet+11) ==0x1) //20 ignores router
// || (*(packet+11) ==0x10)
|| (*(packet+11) ==0x20) //router ignores 20
) {
printf("i%x",*(packet+11));
return 0;
}
/* If we are not the recipient, ignore packets from other RPL nodes */
if (0
|| (*(packet+5) !=0x1) //router
// || (*(packet+11) ==0x10)
// || (*(packet+11) ==0x20) //router ignores 20
) {
printf("r%x",*(packet+11));
return 0;
}
#endif
#endif /* NETSTACK_CONF_WITH_IPV6 */
if(packet_header->caplen > UIP_BUFSIZE) {
return 0;
}
// PRINTF("SIN: %lu\n", packet_header->caplen);
CopyMemory(uip_buf, packet, packet_header->caplen);
return (uint16_t)packet_header->caplen;
}
#ifdef UIP_FALLBACK_INTERFACE
uint16_t
wfall_poll(void)
{
struct pcap_pkthdr *packet_header;
unsigned char *packet;
switch(pcap_next_ex(pfall, &packet_header, &packet)) {
case -1:
error_exit("error on fallback poll\n");
case 0:
return 0;
}
#if NETSTACK_CONF_WITH_IPV6
#if FALLBACK_HAS_ETHERNET_HEADERS
#define ETHERNET_LLADDR_LEN 6
#else
#define ETHERNET_LLADDR_LEN UIP_LLADDR_LEN
#endif
/* Since pcap_setdirection(PCAP_D_IN) is not implemented in winpcap all outgoing packets
* will be echoed back. The stack will ignore any packets not addressed to it, but initial
* ipv6 neighbor solicitations are addressed to everyone and the echoed NS sent on startup
* would be processed as a conflicting NS race which would cause a stack shutdown.
* So discard all packets with our source address (packet starts destaddr, srcaddr, ...)
*
*/
int i;
for (i=0;i<ETHERNET_LLADDR_LEN;i++) if (*(packet+ETHERNET_LLADDR_LEN+i)!=uip_lladdr.addr[i]) break;
if (i==ETHERNET_LLADDR_LEN) {
PRINTF("Discarding echoed packet\n");
return 0;
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
if(packet_header->caplen > UIP_BUFSIZE) {
return 0;
}
PRINTF("FIN: %lu\n", packet_header->caplen);
CopyMemory(uip_buf, packet, packet_header->caplen);
return (uint16_t)packet_header->caplen;
}
#endif
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV6
uint8_t
wpcap_send(const uip_lladdr_t *lladdr)
{
if(lladdr == NULL) {
/* the dest must be multicast*/
(&BUF->dest)->addr[0] = 0x33;
(&BUF->dest)->addr[1] = 0x33;
(&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12];
(&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13];
(&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14];
(&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15];
} else {
//when fallback used this gets ptr to lladdr of all zeroes on forwarded packets, turn them into multicast(?)
if ((lladdr->addr[0]==0)&&(lladdr->addr[1]==0)&&(lladdr->addr[2]==0)&&(lladdr->addr[3]==0)&&(lladdr->addr[4]==0)&&(lladdr->addr[5]==0)) {
(&BUF->dest)->addr[0] = 0x33;
(&BUF->dest)->addr[1] = 0x33;
(&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12];
(&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13];
(&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14];
(&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15];
} else {
memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN);
}
}
memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN);
PRINTF("SUT: %u\n", uip_len);
PRINTF("Src= %02x %02x %02x %02x %02x %02x",(&BUF->src)->addr[0],(&BUF->src)->addr[1],(&BUF->src)->addr[2],(&BUF->src)->addr[3],(&BUF->src)->addr[4],(&BUF->src)->addr[5]);
PRINTF(" Dst= %02x %02x %02x %02x %02x %02x",(&BUF->dest)->addr[0],(&BUF->dest)->addr[1],(&BUF->dest)->addr[2],(&BUF->dest)->addr[3],(&BUF->dest)->addr[4],(&BUF->dest)->addr[5]);
PRINTF(" Type=%04x\n",BUF->type);
BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6);
uip_len += sizeof(struct uip_eth_hdr);
if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) {
error_exit("error on send\n");
}
return 0;
}
#ifdef UIP_FALLBACK_INTERFACE
uint8_t
wfall_send(const uip_lladdr_t *lladdr)
{
#if FALLBACK_HAS_ETHERNET_HEADERS
//make room for ethernet header
//{int i;printf("\n");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
{int i;for(i=uip_len;i>=0;--i) *(char *)(uip_buf+i+14) = *(char *)(uip_buf+i);}
//{int i;printf("\n");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
#endif
if(lladdr == NULL) {
/* the dest must be multicast*/
(&BUF->dest)->addr[0] = 0x33;
(&BUF->dest)->addr[1] = 0x33;
(&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12];
(&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13];
(&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14];
(&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15];
} else {
memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN);
}
memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN);
PRINTF("FUT: %u\n", uip_len);
PRINTF("Srcf= %02x %02x %02x %02x %02x %02x",(&BUF->src)->addr[0],(&BUF->src)->addr[1],(&BUF->src)->addr[2],(&BUF->src)->addr[3],(&BUF->src)->addr[4],(&BUF->src)->addr[5]);
PRINTF(" Dstf= %02x %02x %02x %02x %02x %02x",(&BUF->dest)->addr[0],(&BUF->dest)->addr[1],(&BUF->dest)->addr[2],(&BUF->dest)->addr[3],(&BUF->dest)->addr[4],(&BUF->dest)->addr[5]);
PRINTF(" Typef=%04x\n",BUF->type);
BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6);
uip_len += sizeof(struct uip_eth_hdr);
if(pcap_sendpacket(pfall, uip_buf, uip_len) == -1) {
error_exit("error on fallback send\n");
}
return 0;
}
#endif
#else /* NETSTACK_CONF_WITH_IPV6 */
void
wpcap_send(void)
{
/* if(rand() % 1000 > 900) {
printf("Drop\n");
return;
} else {
printf("Send\n");
}*/
if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) {
error_exit("error on send\n");
}
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
void
wpcap_exit(void)
{
FreeLibrary(wpcap);
}
/*---------------------------------------------------------------------------*/

View File

@ -1,49 +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.
*
* Author: Oliver Schmidt <ol.sc@web.de>
*
*/
#ifndef WPCAP_H_
#define WPCAP_H_
void wpcap_init(void);
uint16_t wpcap_poll(void);
uint16_t wfall_poll(void);
#if NETSTACK_CONF_WITH_IPV6
uint8_t wpcap_send(const uip_lladdr_t *lladdr);
uint8_t wfall_send(const uip_lladdr_t *lladdr);
#else
void wpcap_send(void);
#endif
void wpcap_exit(void);
#endif /* WPCAP_H_ */

View File

@ -45,7 +45,7 @@
#include <string.h>
/*--------------------------------------------------------------------*/
uint8_t
static uint8_t
uip_driver_send(const linkaddr_t *addr)
{
packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len);

View File

@ -17,13 +17,7 @@ ifeq ($(HOST_OS),Windows)
CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c
TARGET_LIBFILES = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a
else
CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c linuxradio-drv.c
#math
ifneq ($(MAKE_NET),MAKE_NET_IPV6)
CONTIKI_TARGET_SOURCEFILES += tapdev.c
else
CONTIKI_TARGET_SOURCEFILES += tapdev6.c
endif
CONTIKI_TARGET_SOURCEFILES += tun6-net.c
endif
CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)

View File

@ -68,6 +68,14 @@ typedef unsigned short uip_stats_t;
#if NETSTACK_CONF_WITH_IPV6
#ifndef NETSTACK_CONF_NETWORK
#define NETSTACK_CONF_NETWORK tun6_net_driver
#endif
#ifndef NETSTACK_CONF_MAC
#define NETSTACK_CONF_MAC nullmac_driver
#endif /* NETSTACK_CONF_MAC */
#ifndef NETSTACK_CONF_RADIO
#define NETSTACK_CONF_RADIO nullradio_driver
#endif /* NETSTACK_CONF_RADIO */

View File

@ -58,6 +58,7 @@
#include "dev/serial-line.h"
#include "net/ipv6/uip.h"
#include "net/ipv6/uip-debug.h"
#include "net/queuebuf.h"
#include "dev/button-sensor.h"
@ -164,6 +165,41 @@ set_lladdr(void)
}
/*---------------------------------------------------------------------------*/
static void
set_global_address(void)
{
static uip_ipaddr_t ipaddr;
static uip_ipaddr_t *prefix = NULL;
int i;
uint8_t state;
/* Assign a unique local address (RFC4193,
http://tools.ietf.org/html/rfc4193). */
if(prefix == NULL) {
uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
} else {
memcpy(&ipaddr, prefix, 8);
}
/* Assumes that the uip_lladdr is set */
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
/* set the PREFIX::1 address to the IF */
uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1);
uip_ds6_defrt_add(&ipaddr, 0);
printf("IPv6 addresses: ");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
printf("\n");
}
}
}
/*---------------------------------------------------------------------------*/
int contiki_argc = 0;
char **contiki_argv;
@ -216,6 +252,7 @@ main(int argc, char **argv)
#ifdef __CYGWIN__
process_start(&wpcap_process, NULL);
#endif
printf("Tentative link-local IPv6 address ");
{
uip_ds6_addr_t *lladdr;
@ -230,6 +267,9 @@ main(int argc, char **argv)
printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
}
set_global_address();
#endif /* NETSTACK_CONF_WITH_IPV6 */
serial_line_init();

View File

@ -74,7 +74,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
/* Generate data until reaching CHUNKS_TOTAL. */
while(strpos < preferred_size) {
strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, "|%ld|", *offset);
strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, "|%ld|", (long) *offset);
}
/* snprintf() does not adjust return value if truncated by size. */

View File

@ -77,7 +77,7 @@ static void
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", event_counter));
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", (unsigned long) event_counter));
/* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */
}

View File

@ -98,11 +98,11 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
* Max-Age might appear in HTTP requests or used for special purposes in CoAP. */
}
if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &longint)) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "MA %lu\n", longint);
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "MA %lu\n", (unsigned long) longint);
/* For HTTP this is the Length option, for CoAP it is the Size option. */
}
if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &longint)) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "SZ %lu\n", longint);
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "SZ %lu\n", (unsigned long) longint);
}
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UH %.*s\n", len, str);
@ -133,7 +133,7 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
}
if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ob %lu\n", coap_pkt->observe);
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ob %lu\n", (unsigned long) coap_pkt->observe);
}
if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "ET 0x");
@ -144,10 +144,10 @@ res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n");
}
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) { /* This getter allows NULL pointers to get only a subset of the block parameters. */
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size);
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B2 %lu%s (%u)\n", (unsigned long) block_num, block_more ? "+" : "", block_size);
}
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size);
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B1 %lu%s (%u)\n", (unsigned long) block_num, block_more ? "+" : "", block_size);
}
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) {
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%.*s", len, bytes);

View File

@ -116,7 +116,7 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
response,
buffer,
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.",
sizeof(large_update_store)));
(unsigned) sizeof(large_update_store)));
return;
}
} else {

View File

@ -68,7 +68,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
/* Generate data until reaching CHUNKS_TOTAL. */
while(strpos < preferred_size) {
strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1,
"|%ld|", *offset);
"|%ld|", (long) *offset);
}
/* snprintf() does not adjust return value if truncated by size. */

View File

@ -53,7 +53,9 @@ RESOURCE(res_plugtest_locquery,
static void
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
#if DEBUG
coap_packet_t *const coap_req = (coap_packet_t *)request;
#endif
PRINTF(
"/location-query POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);

View File

@ -85,7 +85,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
} else {
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
REST.set_response_payload(response, obs_content,
snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter));
snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", (unsigned long) obs_counter));
}
/* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */
}

View File

@ -101,18 +101,20 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
static void
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
coap_packet_t *const coap_req = (coap_packet_t *)request;
PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
#if DEBUG
coap_packet_t *const coap_req = (coap_packet_t *)request;
PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
#endif
REST.set_response_status(response, REST.status.CREATED);
REST.set_header_location(response, "/location1/location2/location3");
}
static void
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
#if DEBUG
coap_packet_t *const coap_req = (coap_packet_t *)request;
PRINTF("/test PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
#endif
if(coap_get_header_if_none_match(request)) {
if(test_none_match_okay) {
@ -152,8 +154,9 @@ res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
static void
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
#if DEBUG
coap_packet_t *const coap_req = (coap_packet_t *)request;
PRINTF("/test DELETE (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
#endif
REST.set_response_status(response, REST.status.DELETED);
}

View File

@ -106,7 +106,9 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
static void
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
#if DEBUG
coap_packet_t *const coap_req = (coap_packet_t *)request;
#endif
PRINTF("/validate PUT ");
PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);

View File

@ -67,7 +67,7 @@ res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferr
*/
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
REST.set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND);
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", event_counter));
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", (unsigned long) event_counter));
/* The REST.subscription_handler() will be called for observable resources by the REST framework. */
}