[Tinyos-2-commits] CVS: tinyos-2.x/support/sdk/c/blip/include 6lowpan.h, NONE, 1.1 IEEE154.h, NONE, 1.1 devconf.h, NONE, 1.1 in_cksum.h, NONE, 1.1 ip.h, NONE, 1.1 ip_malloc.h, NONE, 1.1 lib6lowpan.h, NONE, 1.1

sdhsdh sdhsdh at users.sourceforge.net
Mon Jan 19 16:28:17 PST 2009


Update of /cvsroot/tinyos/tinyos-2.x/support/sdk/c/blip/include
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv6583/support/sdk/c/blip/include

Added Files:
	6lowpan.h IEEE154.h devconf.h in_cksum.h ip.h ip_malloc.h 
	lib6lowpan.h 
Log Message:
 - initial commit of blip (berkeley low-power ip) stack


--- NEW FILE: 6lowpan.h ---
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */


/*
 * Header file for the 6lowpan/IPv6 stack.
 *
 * @author Stephen Dawson-Haggerty
 * 
 */

#ifndef __6LOWPAN_H__
#define __6LOWPAN_H__

#include <stdint.h>
/*
 * Typedefs and static library data.
 */
typedef uint8_t ip6_addr_t [16];
typedef uint16_t cmpr_ip6_addr_t;
#ifdef PC
typedef uint16_t hw_addr_t;
typedef uint16_t hw_pan_t;
enum {
  HW_BROADCAST_ADDR = 0xffff,
};
#else
#include <IEEE802154.h>
#endif

/*
 * shared variables which contain addressing information for 6lowpan
 * devices
 */
extern uint8_t globalPrefix;
extern uint8_t multicast_prefix[8];
extern uint8_t linklocal_prefix[8];

uint8_t cmpPfx(ip6_addr_t a, uint8_t *pfx);

void ip_memclr(uint8_t *buf, uint16_t len);
void *ip_memcpy(void *dst0, const void *src0, uint16_t len);  

/*
 * A packed 6lowpan packet. 
 *
 * The data buffer points at the start of 6lowpan packed data.  We
 * included a few other fields from L2 with this information so that
 * we are able to infer things like source and destination IP from it.
 *
 */
typedef struct packed_lowmsg {
  uint8_t headers;
  uint8_t len;
  // we preprocess the headers bitmap for easy processing.
  hw_addr_t src;
  hw_addr_t dst;
  uint8_t *data;
} packed_lowmsg_t;

/*
 * bit fields we use to keep track of which optional header fields are
 * present in a message
 */
enum {
  LOWMSG_MESH_HDR  = (1 << 0),
  LOWMSG_BCAST_HDR = (1 << 1),
  LOWMSG_FRAG1_HDR = (1 << 2),
  LOWMSG_FRAGN_HDR = (1 << 3),
  LOWMSG_NALP      = (1 << 4),
  LOWMSG_IPNH_HDR  = (1 << 5),
};

/*
 * lengths of different lowpan headers
 */
enum {
  LOWMSG_MESH_LEN = 5,
  LOWMSG_BCAST_LEN = 2,
  LOWMSG_FRAG1_LEN = 4,
  LOWMSG_FRAGN_LEN = 5,
};

enum {
  LOWPAN_LINK_MTU = 110,
  INET_MTU = 1280,
  LIB6LOWPAN_MAX_LEN = LOWPAN_LINK_MTU,
};

/*
 * magic numbers from rfc4944; some of them shifted: mostly dispatch values.
 */
enum {
  LOWPAN_NALP_PATTERN = 0x0,
  LOWPAN_MESH_PATTERN = 0x2,
  LOWPAN_FRAG1_PATTERN = 0x18,
  LOWPAN_FRAGN_PATTERN = 0x1c,
  LOWPAN_BCAST_PATTERN = 0x50,
  LOWPAN_HC1_PATTERN = 0x42,
  LOWPAN_HC_LOCAL_PATTERN = 0x3,
  LOWPAN_HC_CRP_PATTERN = 0x4,
};

enum {
  LOWPAN_MESH_V_MASK = 0x20,
  LOWPAN_MESH_F_MASK = 0x10,
  LOWPAN_MESH_HOPS_MASK = 0x0f,
};

/*
 * IP protocol numbers
 */
enum {
  IANA_ICMP = 58,
  IANA_UDP = 17,
  IANA_TCP = 6,

  NXTHDR_SOURCE = 0,
  NXTHDR_INSTALL   = 253, // Use for experimentation and testing(IANA.org)
  NXTHDR_TOPO      = 252,
  NXTHDR_UNKNOWN = 0xff,
};

#define KNOWN_HEADER(X)  ((X) == NXTHDR_SOURCE || (X) == IANA_UDP || (X) == NXTHDR_INSTALL || (X) == NXTHDR_TOPO)

/*
 * constants to unpack HC-packed headers
 */
enum {
  LOWPAN_IPHC_VTF_MASK      = 0x80,
  LOWPAN_IPHC_VTF_INLINE    = 0,
  LOWPAN_IPHC_NH_MASK       = 0x40,
  LOWPAN_IPHC_NH_INLINE     = 0,
  LOWPAN_IPHC_HLIM_MASK     = 0x20,
  LOWPAN_IPHC_HLIM_INLINE   = 0,

  LOWPAN_IPHC_SC_OFFSET      = 3,
  LOWPAN_IPHC_DST_OFFSET     = 1,
  LOWPAN_IPHC_ADDRFLAGS_MASK = 0x3,

  LOWPAN_IPHC_ADDR_128       = 0x0,
  LOWPAN_IPHC_ADDR_64        = 0x1,
  LOWPAN_IPHC_ADDR_16        = 0x2,
  LOWPAN_IPHC_ADDR_0         = 0x3,

  LOWPAN_IPHC_SHORT_MASK     = 0x80,
  LOWPAN_IPHC_SHORT_LONG_MASK= 0xe0,

  LOWPAN_IPHC_HC1_MCAST      = 0x80,
  LOWPAN_IPHC_HC_MCAST       = 0xa0,

  LOWPAN_HC_MCAST_SCOPE_MASK = 0x1e,
  LOWPAN_HC_MCAST_SCOPE_OFFSET = 1,

  LOWPAN_UDP_PORT_BASE_MASK  = 0xfff0,
  LOWPAN_UDP_PORT_BASE       = 0xf0b0,
  LOWPAN_UDP_DISPATCH        = 0x80,

  LOWPAN_UDP_S_MASK          = 0x40,
  LOWPAN_UDP_D_MASK          = 0x20,
  LOWPAN_UDP_C_MASK          = 0x10,
};


/*
 * nonstandard source routing header fields
 */
enum {
  IP_EXT_SOURCE_DISPATCH    = 0x40,
  IP_EXT_SOURCE_MASK        = 0xc0,

  // dispatch values
  IP_EXT_SOURCE_RECORD      = 0x01,
  IP_EXT_SOURCE_RECORD_MASK = 0x01,
  IP_EXT_SOURCE_INVAL       = 0x02,
  IP_EXT_SOURCE_INVAL_MASK  = 0x02,
  IP_EXT_SOURCE_CONTROLLER  = 0x04,

  // dispatch values for route installation if this flag is set, the
  // source_header must be immediately followed by a
  // source_install_opt struct.
  IP_EXT_SOURCE_INSTALL     = 0x10,
  IP_EXT_SOURCE_INSTALL_MASK= 0x10,

  // indicates weather the forward and reverse paths should be
  // installed.  Are these needed?  the only case when we don't want
  // to install the reverse path is when the destination is a
  // multicast?
  IP_EXT_SOURCE_INST_SRC    = 0x20,
  IP_EXT_SOURCE_INST_DST    = 0x40,
};

#define SH_NENTRIES(SH)   ((sh->len - (sizeof(struct source_header))) / (sizeof(uint16_t)))

struct source_header {
  uint8_t nxt_hdr;
  uint8_t len;
  // the equalivent of the "routing type" field
  uint8_t dispatch;
  uint8_t current;
  uint16_t hops[0];
};

// AT: These are really 16 bit values, but after a certain point the numbers
//  beyond 255 aren't important to us, or rather no different than 255
struct topology_entry {
  uint8_t etx;
  uint8_t conf;
  hw_addr_t hwaddr;
};
struct topology_header {
  uint8_t nxt_hdr;
  uint8_t len;
  struct topology_entry topo[0];
};

enum {
  IP_NUMBER_FRAGMENTS = 12,
};

#endif

--- NEW FILE: IEEE154.h ---
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
#ifndef _IEEE154_H_
#define _IEEE154_H_

typedef struct IEEE154_header {
  uint8_t length;
  uint16_t fcf;
  uint8_t dsn;
  uint16_t destpan;
  uint16_t dest;
  uint16_t src;
} __attribute__((packed)) IEEE154_header_t;

typedef struct serial_header {
  uint16_t dest;
  uint16_t src;
  uint8_t length;
  uint8_t group;
  uint8_t type;
} __attribute__((packed)) serial_header_t;

enum {
  // size of the header not including the length byte
  MAC_HEADER_SIZE = sizeof( IEEE154_header_t ) - 1,
  // size of the footer (FCS field)
  MAC_FOOTER_SIZE = sizeof( uint16_t ),
};

#endif

--- NEW FILE: devconf.h ---
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
#ifndef _CONFIGURE_H_
#define _CONFIGURE_H_

#include "6lowpan.h"

enum {
  CONFIG_ECHO = 0,       // ping the device for status information
  CONFIG_SET_PARM = 1,   // instruct the device to set its hardware addr
  CONFIG_REBOOT = 2,
};

enum {
  CONFIG_ERROR_OK,
  CONFIG_ERROR_FAIL,
  CONFIG_ERROR_BOOTED,
};

#ifndef PC


typedef nx_struct config_cmd {
  nx_uint8_t cmd;
  nx_struct {
    nx_uint16_t retries;
    nx_uint16_t delay;
  } retx;
  nx_struct {
    nx_uint16_t addr;
    nx_uint8_t channel;
  } rf;
} config_cmd_t;


typedef nx_struct {
  nx_uint8_t error;
  nx_uint16_t addr;
  nx_uint16_t serial_read;
  nx_uint16_t radio_read;
  nx_uint16_t serial_fail;
  nx_uint16_t radio_fail;
} config_reply_t; 

#else

enum {
  CONFIGURE_MSG_SIZE = 8,
};
typedef struct config_cmd {
  uint8_t cmd;
  struct {
    uint16_t retries;
    uint16_t delay;
  } retx;
  struct {
    hw_addr_t addr;
    uint8_t channel;
  } rf;
} __attribute__((packed)) config_cmd_t;



typedef struct {
  uint8_t error;
  hw_addr_t addr;
  uint16_t serial_read;
  uint16_t radio_read;
  uint16_t serial_fail;
  uint16_t radio_fail;
} __attribute__((packed)) config_reply_t;

enum {
  TOS_SERIAL_802_15_4_ID = 2,
  TOS_SERIAL_DEVCONF = 3,
};

#endif

#endif


--- NEW FILE: in_cksum.h ---
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
#ifndef _IN_CKSUM_H_
#define _IN_CKSUM_H_

/* in_cksum.h
 * Declaration of  Internet checksum routine.
 *
 * $Id: in_cksum.h,v 1.1 2009/01/20 00:28:15 sdhsdh Exp $
 */

#include <stdint.h>
#include "ip.h"

typedef struct {
	const uint8_t *ptr;
	int	len;
} vec_t;

extern int in_cksum(const vec_t *vec, int veclen);

// extern uint16_t in_cksum(const vec_t *vec, int veclen);

extern uint16_t msg_cksum(struct split_ip_msg *msg, uint8_t nxt_hdr);

#endif

--- NEW FILE: ip.h ---
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
#ifndef _IP_H_
#define _IP_H_

/*
 * define message structures for internet communication
 *
 */

#ifdef PC
#include <linux/if_tun.h>
#include <netinet/in.h>
#endif

#include "6lowpan.h"

enum {
  /*
   * The time, in binary milliseconds, after which we stop waiting for
   * fragments and report a failed receive.  We 
   */
  FRAG_EXPIRE_TIME = 4096,
};


#ifndef PC
// update to use netinet/in definition of an IPv6 address; this is a
//  lot more elegent.
struct in6_addr
  {
    union
      {
	uint8_t	u6_addr8[16];
	uint16_t u6_addr16[8];
	uint32_t u6_addr32[4];
      } in6_u;
#define s6_addr			in6_u.u6_addr8
#define s6_addr16		in6_u.u6_addr16
#define s6_addr32		in6_u.u6_addr32
  };

struct sockaddr_in6 {
  uint16_t sin6_port;
  struct in6_addr sin6_addr;
};
#endif

/*
 * Definition for internet protocol version 6.
 * RFC 2460
 */
struct ip6_hdr {
  uint8_t   vlfc[4];
  uint16_t  plen;          /* payload length */
  uint8_t   nxt_hdr;       /* next header */
  uint8_t   hlim;          /* hop limit */
  struct in6_addr ip6_src; /* source address */
  struct in6_addr ip6_dst; /* destination address */
} __attribute__((packed));

#define IPV6_VERSION            0x6
#define IPV6_VERSION_MASK       0xf0


/*
 * Extension Headers
 */

struct ip6_ext {
  uint8_t nxt_hdr;
  uint8_t len;
  uint8_t data[0];
};

/*
 * icmp
 */
struct  icmp6_hdr {
  uint8_t        type;     /* type field */
  uint8_t        code;     /* code field */
  uint16_t       cksum;    /* checksum field */
};

enum {
    ICMP_TYPE_ECHO_DEST_UNREACH     = 1,
    ICMP_TYPE_ECHO_PKT_TOO_BIG      = 2, 
    ICMP_TYPE_ECHO_TIME_EXCEEDED    = 3,
    ICMP_TYPE_ECHO_PARAM_PROBLEM    = 4,
    ICMP_TYPE_ECHO_REQUEST          = 128,
    ICMP_TYPE_ECHO_REPLY            = 129,
    ICMP_TYPE_ROUTER_SOL            = 133,
    ICMP_TYPE_ROUTER_ADV            = 134,
    ICMP_TYPE_NEIGHBOR_SOL          = 135,
    ICMP_TYPE_NEIGHBOR_ADV          = 136,
    ICMP_NEIGHBOR_HOPLIMIT          = 255,

    ICMP_CODE_HOPLIMIT_EXCEEDED     = 0,
    ICMP_CODE_ASSEMBLY_EXCEEDED     = 1,
};

/*
 * UDP protocol header.
 */
struct udp_hdr {
    uint16_t srcport;               /* source port */
    uint16_t dstport;               /* destination port */
    uint16_t len;                   /* udp length */
    uint16_t chksum;                /* udp checksum */
};

/*
 * TCP transport headers and flags
 */
enum {
  TCP_FLAG_FIN = 0x1,
  TCP_FLAG_SYN = 0x2,
  TCP_FLAG_RST = 0x4,
  TCP_FLAG_PSH = 0x8,
  TCP_FLAG_ACK = 0x10,
  TCP_FLAG_URG = 0x20,
  TCP_FLAG_ECE = 0x40,
  TCP_FLAG_CWR = 0x80,
};

struct tcp_hdr {
  uint16_t srcport;
  uint16_t dstport;
  uint32_t seqno;
  uint32_t ackno;
  uint8_t offset;
  uint8_t flags;
  uint16_t window;
  uint16_t chksum;
  uint16_t urgent;
};

/*
 * IP metadata and routing structures
 */
struct ip_metadata {
  hw_addr_t sender;
  uint8_t   lqi;
  uint8_t   padding[1];
};

struct flow_match {
  cmpr_ip6_addr_t src;
  cmpr_ip6_addr_t dest; // Need to make this more extensible at some point
  cmpr_ip6_addr_t prev_hop;
};

struct rinstall_header {
  struct ip6_ext ext;
  uint16_t flags;
  struct flow_match match;
  uint8_t path_len;
  uint8_t current;
  cmpr_ip6_addr_t path[0];
};

enum {
  R_SRC_FULL_PATH_INSTALL_MASK = 0x01,
  R_DEST_FULL_PATH_INSTALL_MASK = 0x02,
  R_HOP_BY_HOP_PATH_INSTALL_MASK = 0x04,
  R_REVERSE_PATH_INSTALL_MASK = 0x08,
  R_SRC_FULL_PATH_UNINSTALL_MASK = 0x10,
  R_DEST_FULL_PATH_UNINSTALL_MASK = 0x20,
  R_HOP_BY_HOP_PATH_UNINSTALL_MASK = 0x40,
  R_REVERSE_PATH_UNINSTALL_MASK = 0x80,
};

#define IS_FULL_SRC_INSTALL(r) (((r)->flags & R_SRC_FULL_PATH_INSTALL_MASK) == R_SRC_FULL_PATH_INSTALL_MASK)
#define IS_FULL_DST_INSTALL(r) (((r)->flags & R_DEST_FULL_PATH_INSTALL_MASK) == R_DEST_FULL_PATH_INSTALL_MASK)
#define IS_HOP_INSTALL(r) (((r)->flags & R_HOP_BY_HOP_PATH_INSTALL_MASK) == R_HOP_BY_HOP_PATH_INSTALL_MASK)
#define IS_REV_INSTALL(r) (((r)->flags & R_REVERSE_PATH_INSTALL_MASK) == R_REVERSE_PATH_INSTALL_MASK)
#define IS_FULL_SRC_UNINSTALL(r) (((r)->flags & R_SRC_FULL_PATH_UNINSTALL_MASK) == R_SRC_FULL_PATH_UNINSTALL_MASK)
#define IS_FULL_DST_UNINSTALL(r) (((r)->flags & R_DEST_FULL_PATH_UNINSTALL_MASK) == R_DEST_FULL_PATH_UNINSTALL_MASK)
#define IS_HOP_UNINSTALL(r) (((r)->flags & R_HOP_BY_HOP_PATH_UNINSTALL_MASK) == R_HOP_BY_HOP_PATH_UNINSTALL_MASK)
#define IS_REV_UNINSTALL(r) (((r)->flags & R_REVERSE_PATH_UNINSTALL_MASK) == R_REVERSE_PATH_UNINSTALL_MASK)

enum {
  T_INVAL_NEIGH =  0xef,
  T_SET_NEIGH = 0xee,
};

struct flow_id {
  uint16_t src;
  uint16_t dst;
  uint16_t id;
  uint16_t seq;
  uint16_t nxt_hdr;
};


/*
 * These are data structures to hold IP messages.  We used a linked
 * list of headers so that we can easily add extra headers with no
 * copy; similar to the linux iovec's or BSD mbuf structs.  
 * Every split_ip_msg contains a full IPv6 header (40 bytes), but it
 * is placed at the end of the struct so that we can read() a message
 * straight into one of these structs, and then just set up the header
 * chain.
 *
 * Due to the way fragmentation is currently implemented, the total
 * length of the data referenced from this chain must not be longer
 * then what can fit into a single fragment.  This is a limitation of
 * the current fragmentation code, but is perfectly usable in most
 * cases.
 */
struct generic_header {
#ifdef PC
  int payload_malloced:1;
#endif
  uint8_t len;
  union {
    // this could be an eumeration of all the valid headers we can have here.
    struct ip6_ext *ext;
    struct source_header *sh;
    struct udp_hdr *udp;
    struct tcp_hdr *tcp;
    struct rinstall_header *rih;
    struct topology_header *th;
    uint8_t *data;
  } hdr;
  struct generic_header *next;
};

struct split_ip_msg {
  struct generic_header *headers;
  uint16_t data_len;
  uint8_t *data;
#ifdef PC
  struct ip_metadata metadata;
#ifdef DBG_TRACK_FLOWS
  struct flow_id id;
#endif
  // this must be last so we can read() straight into the end of the buffer.
  struct tun_pi pi;
#endif
  struct ip6_hdr hdr;
  uint8_t next[0];
};

/*
 * parse a string representation of an IPv6 address
 */ 
void inet_pton6(char *addr, struct in6_addr *dest);

#endif

--- NEW FILE: ip_malloc.h ---
#ifndef NO_IP_MALLOC
#ifndef IP_MALLOC_H_
#define IP_MALLOC_H_

#include <stdint.h>

// align on this number of byte boundarie#s
#define IP_MALLOC_ALIGN   2
#define IP_MALLOC_LEN     0x0fff
#define IP_MALLOC_FLAGS   0x7000
#define IP_MALLOC_INUSE   0x8000
#define IP_MALLOC_HEAP_SIZE 1500

extern uint8_t heap[IP_MALLOC_HEAP_SIZE];
typedef uint16_t bndrt_t;

void ip_malloc_init();
void *ip_malloc(uint16_t sz);
void ip_free(void *ptr);
uint16_t ip_malloc_freespace();

#ifndef PC
#define malloc(X) ip_malloc(X)
#define free(X)   ip_free(X)
#endif

#endif
#endif

--- NEW FILE: lib6lowpan.h ---
/*
 * "Copyright (c) 2008 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */
#ifndef _LIB6LOWPAN_H_
#define _LIB6LOWPAN_H_

#include <stdint.h>
#include <stddef.h>

#include "6lowpan.h"
#include "ip.h"

#ifdef __TARGET_mips__
// #warning "Using big endian byte order"
#define ntoh16(X)   (X)
#define hton16(X)   (X)
#define ntoh32(X)   (X)
#define hton32(X)   (X)
#define leton16(X)  (((((uint16_t)(X)) << 8) | ((uint16_t)(X) >> 8)) & 0xffff)
#define htole16(X)  leton16(X)
#else
// #warning "Using little endian byte order"
#define ntoh16(X)   (((((uint16_t)(X)) >> 8) | ((uint16_t)(X) << 8)) & 0xffff)
#define hton16(X)   (((((uint16_t)(X)) << 8) | ((uint16_t)(X) >> 8)) & 0xffff)
#define leton16(X)  hton16(X)
#define htole16(X)  (X)
#define ntoh32(X)   ((((uint32_t)(X) >> 24) & 0x000000ff)| \
                     ((((uint32_t)(X) >> 8)) & 0x0000ff00) | \
                     ((((uint32_t)(X) << 8)) & 0x00ff0000) | \
                     ((((uint32_t)(X) << 24)) & 0xff000000))

#define hton32(X)   ((((uint32_t)(X) << 24) & 0xff000000)| \
                     ((((uint32_t)(X) << 8)) & 0x00ff0000) | \
                     ((((uint32_t)(X) >> 8)) & 0x0000ff00) | \
                     ((((uint32_t)(X) >> 24)) & 0x000000ff))
#endif


#define ntohs(X) ntoh16(X)
#define htons(X) hton16(X)

#define ntohl(X) ntoh32(X)
#define htonl(X) hton32(X)


#ifdef DEF_MEMCPY
#define memcpy(X,Y,Z) ip_memcpy(X,Y,Z)
#endif

/*
 * This interface implements the 6loWPAN header structures.  Support
 * for the HC1 and HC2 compressed IP and UDP headers is also
 * available, and the interface is presented in lib6lowpanIP.h.
 *
 */

// only 16-bit address handling modes
#define __6LOWPAN_16BIT_ADDRESS

/*
 *  Library implementation of packing of 6lowpan packets.  
 *
 *  This should allow uniform code treatment between pc and mote code;
 *  the goal is to write ANSI C here...  This means no nx_ types,
 *  unfortunately.
 */

/*
 * 6lowpan header functions
 */

uint16_t getHeaderBitmap(packed_lowmsg_t *lowmsg);
/*
 * Return the length of the buffer required to pack lowmsg
 *  into a buffer.
 */

uint8_t *getLowpanPayload(packed_lowmsg_t *lowmsg);

/*
 * Initialize the header bitmap in 'packed' so that
 *  we know how long the headers are.
 *
 * @return FAIL if the buffer is not long enough.
 */
uint8_t setupHeaders(packed_lowmsg_t *packed, uint16_t headers);

/*
 * Test if various protocol features are enabled
 */
uint8_t hasMeshHeader(packed_lowmsg_t *msg);
uint8_t hasBcastHeader(packed_lowmsg_t *msg);
uint8_t hasFrag1Header(packed_lowmsg_t *msg);
uint8_t hasFragNHeader(packed_lowmsg_t *msg);

/*
 * Mesh header fields
 *
 *  return FAIL if the message doesn't have a mesh header
 */
uint8_t getMeshHopsLeft(packed_lowmsg_t *msg, uint8_t *hops);
uint8_t getMeshOriginAddr(packed_lowmsg_t *msg, hw_addr_t *origin);
uint8_t getMeshFinalAddr(packed_lowmsg_t *msg, hw_addr_t *final);

uint8_t setMeshHopsLeft(packed_lowmsg_t *msg, uint8_t hops);
uint8_t setMeshOriginAddr(packed_lowmsg_t *msg, hw_addr_t origin);
uint8_t setMeshFinalAddr(packed_lowmsg_t *msg, hw_addr_t final);

/*
 * Broadcast header fields
 */
uint8_t getBcastSeqno(packed_lowmsg_t *msg, uint8_t *seqno);

uint8_t setBcastSeqno(packed_lowmsg_t *msg, uint8_t seqno);

/*
 * Fragmentation header fields
 */
uint8_t getFragDgramSize(packed_lowmsg_t *msg, uint16_t *size);
uint8_t getFragDgramTag(packed_lowmsg_t *msg, uint16_t *tag);
uint8_t getFragDgramOffset(packed_lowmsg_t *msg, uint8_t *size);

uint8_t setFragDgramSize(packed_lowmsg_t *msg, uint16_t size);
uint8_t setFragDgramTag(packed_lowmsg_t *msg, uint16_t tag);
uint8_t setFragDgramOffset(packed_lowmsg_t *msg, uint8_t size);

/*
 * IP header compression functions
 *
 */
int getCompressedLen(packed_lowmsg_t *pkt);

/*
 * Pack the header fields of msg into buffer 'buf'.
 *  it returns the number of bytes written to 'buf', or zero if it encountered a problem.
 *
 * it will pack the IP header and all headers in the header chain of
 * msg into the buffer; the only thing it will not pack is the
 * payload.
 */
uint8_t packHeaders(struct split_ip_msg *msg,
                    uint8_t *buf, uint8_t len);
/*
 * Unpack the packed data from pkt into dest.
 *
 * It turns out that we need to keep track of a lot of different
 * locations in order to be able to unpack and forward efficiently.
 * If we don't save these during the unpack, we end up reconstructing
 * them in various places so it's less error-prone to compute them
 * while we're parsing the packed fields.
 */
typedef struct {
  // the final header in the header chain; should be the transport header
  uint8_t nxt_hdr;
  // a pointer to the point in the source where we stopped unpacking
  uint8_t *payload_start;
  // a pointer to the point in the destination right after all headers
  uint8_t *header_end;
  // the total, uncompressed length of the headers which were unpacked
  uint8_t payload_offset;
  // points to the hop limit field of the packet message
  uint8_t *hlim;
  // points to the tranport header in the destination region, 
  //  if it was within the unpacked region header.
  //  if it was not, it is the same as header_end
  uint8_t *transport_ptr;
  // points to the source header within the packed fields, IF it contains one.
  struct source_header *sh;
  struct rinstall_header *rih;
} unpack_info_t;

uint8_t *unpackHeaders(packed_lowmsg_t *pkt, unpack_info_t *u_info,
                       uint8_t *dest, uint16_t len);

/*
 * Fragmentation routines.
 */

extern uint16_t lib6lowpan_frag_tag;

typedef struct {
  uint16_t tag;            /* datagram label */
  uint16_t size;           /* the size of the packet we are reconstructing */
  void    *buf;            /* the reconstruction location */
  uint16_t bytes_rcvd;     /* how many bytes from the packet we have
                              received so far */
  uint8_t timeout;
  uint8_t *transport_hdr;
  struct ip_metadata metadata;
} reconstruct_t;

typedef struct {
  uint16_t tag;    /* the label of the datagram */
  uint16_t offset; /* how far into the packet we have sent, in bytes */
} fragment_t;


/*
 *  this function writes the next fragment which needs to be sent into
 *  the buffer passed in.  It updates the structures in process to
 *  reflect how much of the packet has been sent so far.
 *
 *  if the packet does not require fragmentation, this function will
 *  not insert a fragmentation header and will merely compress the
 *  headers into the packet.
 *
 */
uint8_t getNextFrag(struct split_ip_msg *msg, fragment_t *progress,
                    uint8_t *buf, uint16_t len);


enum {
  T_FAILED1 = 0,
  T_FAILED2 = 1,
  T_UNUSED =  2,
  T_ACTIVE =  3,
  T_ZOMBIE =  4,
};

uint8_t* getLinkLocalPrefix();
#endif



More information about the Tinyos-2-commits mailing list