X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=support%2Fsdk%2Fc%2Fblip%2Flib6lowpan%2Fip.h;fp=support%2Fsdk%2Fc%2Fblip%2Flib6lowpan%2Fip.h;h=6a4be2cd06072fc005c4092fe35ecb592e6ca713;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hp=0000000000000000000000000000000000000000;hpb=adf1de6c009d13b7b52e68535c63b28f59c97400;p=tinyos-2.x.git diff --git a/support/sdk/c/blip/lib6lowpan/ip.h b/support/sdk/c/blip/lib6lowpan/ip.h new file mode 100644 index 00000000..6a4be2cd --- /dev/null +++ b/support/sdk/c/blip/lib6lowpan/ip.h @@ -0,0 +1,332 @@ +/* + * "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 +#include +#endif + +#include "6lowpan.h" +#include "blip-platform.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]; +}; + +struct tlv_hdr { + uint8_t type; + uint8_t len; +}; +/* + * IP protocol numbers + */ +enum { + IANA_ICMP = 58, + IANA_UDP = 17, + IANA_TCP = 6, + + // IPV6 defined extention header types. All other next header + // values are supposed to be transport protocols, with TLVs used + IPV6_HOP = 0, + IPV6_DEST = 60, + IPV6_ROUTING = 43, + IPV6_FRAG = 44, + IPV6_AUTH = 51, + IPV6_SEC = 50, + IPV6_MOBILITY = 135, + IPV6_NONEXT = 59, +}; +#define EXTENSION_HEADER(X) ((X) == IPV6_HOP || (X) == IPV6_ROUTING || (X) == IPV6_DEST) +#define COMPRESSIBLE_TRANSPORT(X) ((X) == IANA_UDP) + +/* + * nonstandard source routing header fields + */ +enum { + IP6ROUTE_TYPE_SOURCE = 0, + IP6ROUTE_TYPE_INVAL = 1, + IP6ROUTE_FLAG_CONTROLLER = 0x8, + IP6ROUTE_FLAG_MASK = IP6ROUTE_FLAG_CONTROLLER, + + IP_EXT_SOURCE_DISPATCH = 0x40, + IP_EXT_SOURCE_MASK = 0xc0, + + // dispatch values + IP_EXT_SOURCE_CONTROLLER = 0x40, + + // 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, + + // a topology TLV inside a destination option + TLV_TYPE_TOPOLOGY = 0x0a, + // a route install message, inside a hop-by-hop or destination + // option message. + TLV_TYPE_INSTALL = 0x0b, + TLV_TYPE_FLOW = 0x0c, + TLV_TYPE_MCASTSEQ = 0x0d, +}; + +struct ip6_route { + uint8_t nxt_hdr; + uint8_t len; + uint8_t type; + uint8_t segs_remain; + uint16_t hops[0]; +}; +#define ROUTE_NENTRIES(SH) (((SH)->len - (sizeof(struct ip6_route))) / (sizeof(uint16_t))) + + +/* + * 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 { + ieee154_saddr_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 +}; + +struct rinstall_header { + struct flow_match match; + uint8_t flags; + uint8_t path_len; + cmpr_ip6_addr_t path[0]; +}; + +enum { + // is this a hop-by-hop or source install command + HYDRO_INSTALL_METHOD_MASK = 0x03, + HYDRO_METHOD_HOP = 0x01, + HYDRO_METHOD_SOURCE = 0x02, + + // should we also apply the action to the reverse path? + HYDRO_INSTALL_REVERSE = 0x04, + + // is this an uninstallation? + HYDRO_INSTALL_UNINSTALL_MASK = 0x08, + +}; + +enum { + T_INVAL_NEIGH = 0xef, + T_SET_NEIGH = 0xee, +}; + + +/* + * 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 ip6_route *sh; + struct udp_hdr *udp; + uint8_t *data; + } hdr; + struct generic_header *next; +}; + +enum { + IP_NOHEADERS = 1 << 0, + IP_MCAST = 1 << 1, + IP_NOADDRESS = 1 << 2, +}; + +struct split_ip_msg { + struct generic_header *headers; + uint16_t data_len; + uint8_t *data; +#ifdef PC + uint16_t foo; + uint16_t flow_id; + uint16_t prev_hop; + struct ip_metadata metadata; + // 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]; +}; + +#ifndef NO_LIB6LOWPAN_ASCII +/* + * parse a string representation of an IPv6 address + */ +void inet_pton6(char *addr, struct in6_addr *dest); +int inet_ntop6(struct in6_addr *addr, char *buf, int cnt); +#endif + +#endif