📄 ipp.nc
字号:
/* * Copyright (c) 2007 Matus Harvan * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * 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 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 * OWNER 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. *//* * Parts of the 6lowpan implementation design were inspired Andrew * Christian's port of Adam Dunkel's uIP to TinyOS 1.x. This work is * distributed under the following copyrights: * * 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. * * Copyright (c) 2005, Hewlett-Packard Company * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of the Hewlett-Packard Company 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 * OWNER 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. *//* * The actual implementaion of the 6lowpan/IPv6 stack lives in this file. */#include "IP.h"#include "IP_internal.h"#include "message.h"#ifdef ENABLE_PRINTF_DEBUG#include "printf.h"#endif /* ENABLE_PRINTF_DEBUG */module IPP { provides { interface SplitControl as IPControl; interface IP; interface UDPClient[uint8_t i]; } uses { interface Timer<TMilli> as Timer; interface Pool<lowpan_pkt_t> as SendPktPool; interface Pool<app_data_t> as AppDataPool; interface Pool<frag_info_t> as FragInfoPool; interface SplitControl as MessageControl; interface Receive; interface AMSend; interface Packet; interface AMPacket;#ifdef ENABLE_PRINTF_DEBUG interface PrintfFlush; interface SplitControl as PrintfControl;#endif /* ENABLE_PRINTF_DEBUG */ interface Leds; }} implementation { /* global variables */ enum { COUNT_UDP_CLIENT = uniqueCount("UDPClient"), COUNT_UDP_CONNS = COUNT_UDP_CLIENT }; ip6_addr_t global_addr; ip6_addr_t linklocal_addr; uint16_t g_dgram_tag = 0; uint16_t uip_len, uip_slen; uint8_t uip_flags; /* The uip_flags variable is used for communication between the TCP/IP stack and the application program. */ message_t g_msg; // AM for sending lowpan_pkt_t rx_pkt; // packet used for receiving //struct lowpan_pkt send_pkt[SEND_PKTS]; // packets to be sent lowpan_pkt_t *send_queue; // packets to be sent - queue frag_buf_t frag_bufs[FRAG_BUFS]; // fragment reassembly buffers struct udp_conn udp_conns[COUNT_UDP_CONNS]; static uint16_t lastport; /* Keeps track of the last port used for a new connection. */ static int g_send_pending = 0; // Pre-declare // clear all fields, set app_data = NULL void lowpan_pkt_clear(lowpan_pkt_t *pkt); int ip6_addr_cmp(const ip6_addr_t *a, const ip6_addr_t *b); static void dump_serial_packet(const unsigned char *packet, const int len);/*---------------------------------------------------------------------------*//* from http://www.nabble.com/memcpy-assumes-16-bit-alignment--t712619.html */void * my_memcpy(void *dst0, const void *src0, size_t len) { char *dst = (char *)dst0; const char *src = (const char *)src0; void *ret = dst0; for (; len > 0; len--) *dst++ = *src++; return ret; }/* * Use this function for copying/setting/memset() 16-bit values * on the MSP430 !!! * * The mspgcc compiler geenrates broken code when doing memset with 16 * bit values, i.e. things go wrong if they are not aligned at 16-bit * boundaries. See * http://www.nabble.com/msp430-gcc-generating-unaligned-access.-t2261862.html * and page 25 in http://www.eecs.harvard.edu/~konrad/projects/motetrack/mspgcc-manual-20031127.pdf for details. *//* use when DST may be UNALIGNED */inline void set_16t(void *dst, uint16_t val){ *((uint8_t*)dst) = *((uint8_t*)&val); *(((uint8_t*)dst)+1) = *(((uint8_t*)&val)+1); //memcpy((uint8_t*)dst, (uint8_t*)&val, sizeof(uint8_t)); //memcpy(((uint8_t*)dst)+1, ((uint8_t*)&val)+1, sizeof(uint8_t));}/* use when SRC may be UNALIGNED */inline uint16_t get_16t(void *val){ uint16_t tmp; *((uint8_t*)&tmp) = *((uint8_t*)val); *(((uint8_t*)&tmp)+1) = *(((uint8_t*)val)+1); //memcpy((uint8_t*)&tmp, (uint8_t*)val, sizeof(uint8_t)); //memcpy(((uint8_t*)&tmp)+1, ((uint8_t*)val)+1, sizeof(uint8_t)); return tmp;} inline uint16_t htons( uint16_t val ) { // The MSB is little-endian; network order is big return ((val & 0xff) << 8) | ((val & 0xff00) >> 8); } inline uint16_t ntohs( uint16_t val ) { // The MSB is little-endian; network order is big return ((val & 0xff) << 8) | ((val & 0xff00) >> 8); } inline void htonl( uint32_t val, uint8_t *dest ) { dest[0] = (val & 0xff000000) >> 24; dest[1] = (val & 0x00ff0000) >> 16; dest[2] = (val & 0x0000ff00) >> 8; dest[3] = (val & 0x000000ff); } inline uint32_t ntohl( uint8_t *src ) { return (((uint32_t) src[0]) << 24) | (((uint32_t) src[1]) << 16) | (((uint32_t) src[2]) << 8) | (((uint32_t) src[3])); } /* inline void uip_pack_ipaddr( ip6_addr_t *addr, uint8_t *new_addr) { memcpy(addr, new_addr, sizeof(addr)); } // Unpack the IP address into an array of octet inline void uip_unpack_ipaddr( uint8_t *in, uint8_t *out ) { memcpy(out, in, sizeof(ip6_addr_t)); } *//*---------------------------------------------------------------------------*/ /* This should be optimized for aligned and unaligned case */ static uint16_t ip_chksum(const uint8_t *buf, uint16_t len, uint16_t acc) { uint16_t v; for (; len > 1; len -= 2) { v = (((uint16_t) buf[1]) << 8) | ((uint16_t) buf[0]); if ( (acc += v) < v ) acc++; buf += 2; } // add an odd byte (note we pad with 0) if (len) { v = (uint16_t) buf[0]; if ( (acc += v) < v ) acc++; } return acc; } /* * IPv6 checksum of the pseudo-header (RFC 2460, Sec 8.1) * src_addr and dst_addr are in nerwork byte order * len is in host byte order (will internally be converted) */ static uint16_t ipv6_chksum(const ip6_addr_t* src_addr, const ip6_addr_t* dst_addr, const uint8_t next_header, const uint16_t upper_layer_len, uint16_t acc) { uint16_t tmp; /* source address */ acc = ip_chksum((const uint8_t *) src_addr, sizeof(*src_addr), acc); /* destination address */ acc = ip_chksum((const uint8_t *) dst_addr, sizeof(*dst_addr), acc); /* upper-layer packet length */ tmp = htons(upper_layer_len); acc = ip_chksum((const uint8_t *) &tmp, sizeof(tmp), acc); /* next header */ tmp = htons(next_header); acc = ip_chksum((const uint8_t *) &tmp, sizeof(tmp), acc); return acc; } /* same as above, but including the uppel-layer buffer */ static uint16_t ipv6_chksum_data(const ip6_addr_t* src_addr, const ip6_addr_t* dst_addr, const uint8_t next_header, const uint8_t *data, uint16_t data_len, uint16_t acc) { /* upper-layer payload */ acc = ip_chksum(data, data_len, acc); return ipv6_chksum(src_addr, dst_addr, next_header, data_len, acc); }/*---------------------------------------------------------------------------*/ bool ipv6_addr_is_zero(const ip6_addr_t *addr) { int i; for (i=0;i<16;i++) { if (addr->addr[i]) { return FALSE; } } return TRUE; } bool ipv6_addr_is_linklocal_unicast(const ip6_addr_t *addr) { if ( addr->addr[0] == 0xFE && addr->addr[1] == 0x80 && addr->addr[2] == 0 && addr->addr[3] == 0 && addr->addr[4] == 0 && addr->addr[5] == 0 && addr->addr[6] == 0 && addr->addr[7] == 0 ) return TRUE; else return FALSE; } //TODO: prepend pan_id once we have a proper 802.15.4 stackvoid ipv6_iface_id_from_am_addr(am_addr_t am_addr, uint8_t *host_part){ memset(host_part, 0, 6); host_part[4] = 0xFF; host_part[5] = 0xFE; host_part += 6; set_16t(host_part, htons(am_addr));}void ipv6_iface_id_from_hw_addr(hw_addr_t *hw_addr, uint8_t *host_part){ if (hw_addr->type == HW_ADDR_SHORT) { memset(host_part, 0, 6); host_part[4] = 0xFF; host_part[5] = 0xFE; host_part[7] = hw_addr->addr_short[0]; host_part[8] = hw_addr->addr_short[1]; //ipv6_iface_id_from_am_addr(hw_addr->addr_short, host_part); } else { //TODO }} bool ipv6_addr_is_linklocal_multicast(const ip6_addr_t *addr){ if (addr->addr[0] == 0xFF && addr->addr[1] == 0x02) return TRUE; else return FALSE;}bool ipv6_addr_is_linklocal(const ip6_addr_t *addr){ return (ipv6_addr_is_linklocal_unicast(addr) || ipv6_addr_is_linklocal_multicast(addr));}bool ipv6_addr_is_linklocal_allnodes(const ip6_addr_t *addr){ //TODO: interface-local addr FF01::1 if ( addr->addr[0] == 0xFF && addr->addr[1] == 0x02 && addr->addr[2] == 0 && addr->addr[3] == 0 && addr->addr[4] == 0 && addr->addr[5] == 0 && addr->addr[6] == 0 && addr->addr[7] == 0 && addr->addr[8] == 0 && addr->addr[9] == 0 && addr->addr[10] == 0 && addr->addr[11] == 0 && addr->addr[12] == 0 && addr->addr[13] == 0 && addr->addr[14] == 0 && addr->addr[15] == 0x01 ) return TRUE; else return FALSE;}bool ipv6_addr_is_solicited_node_multicast_prefix(const ip6_addr_t *addr){// Solicited-Node Address: FF02:0:0:0:0:1:FFXX:XXXX// Solicited-Node multicast address are computed as a function of a// node's unicast and anycast addresses. A Solicited-Node multicast// address is formed by taking the low-order 24 bits of an address// (unicast or anycast) and appending those bits to the prefix// FF02:0:0:0:0:1:FF00::/104 resulting in a multicast address in the// range// FF02:0:0:0:0:1:FF00:0000// to// FF02:0:0:0:0:1:FFFF:FFFF if ( addr->addr[0] == 0xFF && addr->addr[1] == 0x02 && addr->addr[2] == 0 && addr->addr[3] == 0 && addr->addr[4] == 0 && addr->addr[5] == 0 && addr->addr[6] == 0 && addr->addr[7] == 0 && addr->addr[8] == 0 && addr->addr[9] == 0 && addr->addr[10] == 0 && addr->addr[11] == 0x01 && addr->addr[12] == 0xFF ) return TRUE; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -