00001 /* 00002 * Copyright (c) 2010, FIP AUTHORS 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1) Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * 2) Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * 3) Neither the name of the FIP AUTHORS nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software 00017 * without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 */ 00031 /** 00032 * @file 00033 * This file contains definitions and macros which are used 00034 * within both fip and the user application which uses fip. 00035 * 00036 * @author 00037 * Colin O'Flynn 00038 */ 00039 00040 #ifndef FIP_H_ 00041 #define FIP_H_ 00042 00043 #include <stdint.h> 00044 #include "fip_config.h" 00045 #include "fip_compiler.h" 00046 #include "fip_timer.h" 00047 #include "fip_trace.h" 00048 #include <string.h> 00049 00050 /* ################################## FIP DEFINES ############################# */ 00051 00052 #define FIP_IPHDR_V6 0x60 00053 #define FIP_IPHDR_V6_ZEROTCFLOW 0x60000000 00054 #define FIP_IPHDR_V4 0x40 00055 #define FIP_IPV6_HDR_LEN 40 00056 00057 /* From: http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml */ 00058 #define FIP_IPHDR_PROTO_TCP 6 00059 #define FIP_IPHDR_PROTO_UDP 17 00060 #define FIP_IPHDR_PROTO_ICMP6 58 00061 #define FIP_IPHDR_PROTO_NONEXT6 59 00062 #define FIP_IPHDR_PROTO_EXT_HOPBYHOP 0 00063 #define FIP_IPHDR_PROTO_EXT_ROUTING 43 00064 #define FIP_IPHDR_PROTO_EXT_FRAG 44 00065 #define FIP_IPHDR_PROTO_EXT_ESP 50 00066 #define FIP_IPHDR_PROTO_EXT_AH 51 00067 #define FIP_IPHDR_PROTO_EXT_DEST 60 00068 00069 /* From RFC2460 */ 00070 #define FIP_EXTHDR_OPT_ACTIONMASK 0xC0 00071 /** skip over this option and continue processing the header.*/ 00072 #define FIP_EXTHDR_OPT_ACTIONSKIP (0<<6) 00073 00074 /**< discard the packet. */ 00075 #define FIP_EXTHDR_OPT_ACTIONDROP (1<<6) 00076 00077 /**< discard the packet and, regardless of whether or not the 00078 packet's Destination Address was a multicast address, send an 00079 ICMP Parameter Problem, Code 2, message to the packet's 00080 Source Address, pointing to the unrecognized Option Type. */ 00081 #define FIP_EXTHDR_OPT_ACTIONFORCE (2<<6) 00082 00083 /**< discard the packet and, only if the packet's Destination 00084 Address was not a multicast address, send an ICMP Parameter 00085 Problem, Code 2, message to the packet's Source Address, 00086 pointing to the unrecognized Option Type. */ 00087 #define FIP_EXTHDR_OPT_ACTIONERROR (3<<6) 00088 00089 #define DELAY_FIRST_PROBE_TIME 5000 00090 #define FIP_IPFRAG_EXPIRETIME 60 00091 00092 /* From RFC4443 */ 00093 #define FIP_ICMPV6_TYPE_ECHOREQUEST 128 00094 #define FIP_ICMPV6_TYPE_ECHOREPLY 129 00095 00096 #define FIP_ICMPV6_TYPE_ERRORREACH 1 00097 #define FIP_ICMPV6_CODE_ERRORROUTE 0 /**< Dest Unreachable: No route to dest */ 00098 #define FIP_ICMPV6_CODE_ERRORPROHIBIT 1 /**< Dest Unreachable: Administratively Prohibited*/ 00099 #define FIP_ICMPV6_CODE_ERRORSCOPE 2 /**< Dest Unreachable: Beyond scope of source address */ 00100 #define FIP_ICMPV6_CODE_ERRORADDR 3 /**< Dest Unreachable: Address unreachable */ 00101 #define FIP_ICMPV6_CODE_ERRORPORT 4 /**< Dest Unreachable: Port unreachable */ 00102 #define FIP_ICMPV6_CODE_ERRORPOLICY 5 /**< Dest Unreachable: Source address failed ingress/egress policy */ 00103 #define FIP_ICMPV6_CODE_ERRORREJECT 6 /**< Dest Unreachable: Reject route to destination */ 00104 00105 #define FIP_ICMPV6_TYPE_ERRORBIG 2 00106 00107 #define FIP_ICMPV6_TYPE_ERRORTIME 3 00108 #define FIP_ICMPV6_CODE_ERRORTTL 0 /**< Time Exceeded: Hop limit exceeded in transit */ 00109 #define FIP_ICMPV6_CODE_ERRORFRAG 1 /**< Time Exceeded: Fragment reassembly time exceeded */ 00110 00111 #define FIP_ICMPV6_TYPE_ERRORPARAM 4 00112 #define FIP_ICMPV6_CODE_ERRORGENERAL 0 /**< Parameter Problem: Erroneous header field encountered */ 00113 #define FIP_ICMPV6_CODE_ERRORNH 1 /**< Parameter Problem: Unrecognized Next Header type encountered */ 00114 #define FIP_ICMPV6_CODE_ERROROPT 2 /**< Parameter Problem: Unrecognized IPv6 option encountered */ 00115 00116 00117 /* ################################## FIP TYPES ############################### */ 00118 /** 00119 * @addtogroup fip_types 00120 * @{ 00121 */ 00122 00123 /** The return value used when functions are only returning a status, and nothing else. */ 00124 typedef enum 00125 { 00126 RV_OK = 0, /**< Everything was OK */ //!< RV_OK 00127 RV_UNKNOWN_ERROR, /**< An unknown error occurred */ //!< RV_UNKNOWN_ERROR 00128 RV_MEMORY_ERROR, /**< A dynamic memory allocation error occurred, such as malloc failing */ //!< RV_MEMORY_ERROR 00129 RV_PARAMETER_ERROR, /**< Parameter passed was invalid */ //!< RV_PARAMETER_ERROR 00130 RV_UNHANDLED, /**< Function could not handle request */ //!< RV_UNHANDLED 00131 RV_ND6_INVALID_STATE, /**< ND Specific: Invalid State */ //!< RV_ND6_INVALID_STATE 00132 RV_ND6_NOENTRY, /**< ND Specific: No Entry */ //!< RV_ND6_NOENTRY 00133 RV_RH4_SEGMENT_LEFT_ERROR, /**< There was a problem with the segments left */ //!< RV_RH4_SEGMENT_LEFT_ERROR 00134 RV_RH4_HOPS_EXCEEDED, /**< Hop limit exceeded. */ //!< RV_RH4_HOPS_EXCEEDED 00135 RV_RH4_ADDRESS_OFF_LINK, /**< An address in the source route was not on link. */ //!< RV_RH4_ADDRESS_OFF_LINK 00136 RV_RH4_PROCESS_NEXT_HEADER, /**< draft-hui-6man-rpl-routing-header-02, page 9, packet has arrived at destination. *///!< RV_RH4_PROCESS_NEXT_HEADER 00137 RV_HBH_RPL_INSTANCE_ERROR, /**< Cannot forward packet due to unknown RPL instance ID. */ //!< RV_HBH_RPL_INSTANCE_ERROR 00138 RV_HBH_RANK_ERROR /**< Rank error detected, packet dropped. */ //!< RV_HBH_RANK_ERROR 00139 00140 } fip_return_t; 00141 00142 typedef enum 00143 { 00144 IPV4, 00145 IPV6 00146 } fip_ipversion_t; 00147 00148 /* If your compiler isn't C99, use this: 00149 * typedef enum { 00150 * false = 0, 00151 * true 00152 * } fip_bool_t; 00153 */ 00154 #include <stdbool.h> 00155 /** Typedef the C99 bool type. Done in a typedef in case your compiler is not C99 compliant */ 00156 typedef bool fip_bool_t; 00157 00158 typedef enum 00159 { 00160 tribool_untested, 00161 tribool_false, 00162 tribool_true 00163 } fip_tribool_t; 00164 00165 typedef unsigned char fip_ifnum_t; 00166 00167 typedef unsigned char fip_ipnum_t; 00168 #define FIP_IPNUM_UNKNOWN 0xFF 00169 00170 /** Address life-times */ 00171 typedef uint32_t fip_vlifetime_t; 00172 00173 /** Address types. Note these correspond to uIP's ADDR_ANYTYPE, ADDR_AUTCONF, 00174 * ADDR_DHCP, and ADDR_MANUAL. Thus you can cast between code using fip_addrtype_t and 00175 * code using uint8_t with uIP's defines. */ 00176 typedef enum 00177 { 00178 ADDR_UNKNOWN = 0, /**< Unknown address type */ 00179 ADDR_AUTOCONF = 1, /**< Autoconfigured address type */ 00180 ADDR_STATEFUL = 2, /**< Statefully assigned (ie: DHCP) */ 00181 ADDR_MANUAL = 3, /**< Manually assigned */ 00182 ADDR_MULTICAST /**< Multicast */ 00183 }fip_addrtype_t; 00184 00185 /** State of prefix in use on an interface */ 00186 typedef enum 00187 { 00188 PREFIX_UNUSED = 0, /**< Prefix not used */ 00189 PREFIX_USED /**< Prefix used */ 00190 }fip_prefixstate_t; 00191 00192 /** State of route in use on an interface */ 00193 typedef enum 00194 { 00195 ROUTE_UNUSED = 0, /**< Route not used */ 00196 ROUTE_USED /**< Route used */ 00197 }fip_routestate_t; 00198 00199 /** State of address in use on an interface. Note this does NOT map directly to 00200 * uIP's address states (ADDR_TENATIVE, etc) as this enumeration adds an 'unused' 00201 * state. */ 00202 typedef enum 00203 { 00204 ADDR_UNUSED = 0, /**< Adddress not used */ 00205 ADDR_NEW, /**< New address, DAD may be required before can be used */ 00206 ADDR_TENATIVE, /**< Address tenative, waiting for DAD to finish */ 00207 ADDR_OPTIMISTIC, /**< Address has optimistically been assigned */ 00208 ADDR_PREFERRED, /**< Preferred address to use */ 00209 ADDR_DEPRECATED, /**< Address deprecated, probably as it expired */ 00210 ADDR_DUPLICATE, /**< Duplicate address, do not use */ 00211 ADDR_DELETE /**< Address being deleted */ 00212 } fip_addrstate_t; 00213 00214 typedef struct 00215 { 00216 uint8_t addr[FIP_CONF_LLADDR_LEN]; /**< The address */ 00217 unsigned char len; /**< Length of address */ 00218 } fip_lladdr_t; 00219 00220 typedef struct 00221 { 00222 fip_lladdr_t lladdr; /**< The link-layer address */ 00223 fip_bool_t validForGPAuto; /**< Valid for IPv6 Global Prefix auto-configuration */ 00224 } fip_mylladdr_t; 00225 00226 typedef struct 00227 { 00228 uint8_t * addr; /**< Pointer to the address */ 00229 unsigned char len; /**< Length of address */ 00230 } fip_llptraddr_t; 00231 00232 /** Holds flags with additional information about any addresses. If you add/modify this 00233 * definition (to add new flags), you must modify the @ref fip_packet_resetAddrFlags 00234 * macro as well. */ 00235 typedef struct 00236 { 00237 fip_tribool_t isMySolicitedNode; /**< Is address my solicited node? */ 00238 fip_tribool_t isUnspecified; /**< Is address unspecified? */ 00239 fip_tribool_t isLinkLocal; /**< Is this address a link-local (fe80::) address? */ 00240 fip_tribool_t isOnLink; /**< Is this address on-link? */ 00241 } fip_ip6addr_flags_t; 00242 00243 /** IPv6 address, held as an array of 16 bytes */ 00244 typedef struct 00245 { 00246 uint8_t addr[16]; 00247 } fip_ip6addr_t; 00248 00249 /** IPv6 address with additional state */ 00250 typedef struct 00251 { 00252 fip_addrstate_t state; /**< Address state (unused, new, etc) */ 00253 fip_addrtype_t type; /**< Address type (autoconf, manual, etc) */ 00254 fip_ip6addr_t addr; /**< IPv6 Address */ 00255 fip_vlifetime_t vlifetime; /**< IPv6 Lifetime */ 00256 unsigned char hasSolicitedMulticast:1; /**< Flag to indicate should base a multicast on this */ 00257 unsigned char hasPreferredLLIndex:1; /**< Flag to indicate there is a preferred LL address */ 00258 unsigned char preferredLLIndex; /**< Index to preferred LL address to use */ 00259 unsigned char dupAddrDetectLeft; /**< Number of DAD Transmissions left */ 00260 fip_timer32mS_t retransExpire32mS; /**< Timer for DAD */ 00261 } fip_myip6addr_t; 00262 00263 /** IPv6 Prefix with additional state */ 00264 typedef struct 00265 { 00266 fip_prefixstate_t state; /**< Prefix state (unused, new, etc) */ 00267 unsigned char length; /**< Prefix length in bits */ 00268 unsigned char advPrefix : 1; /**< For routers, flag that indicates if we advertise this prefix */ 00269 unsigned char isOnLink : 1; /**< Is prefix known to be on-link? */ 00270 fip_vlifetime_t validLifetime; /**< How long the prefix is valid for, used when advertising the prefix */ 00271 fip_vlifetime_t validUntil; /**< When in seconds since system start the address expires, 0 = Never */ 00272 fip_ip6addr_t prefix; /**< Prefix itself */ 00273 } fip_myip6prefix_t; 00274 00275 /** IPv6 Default Router with additional state */ 00276 typedef struct 00277 { 00278 fip_routestate_t state; /**< State (unused, new, etc) */ 00279 fip_vlifetime_t validUntil32S; /**< When in seconds since system start this defrouter expires, 0 = Never */ 00280 fip_ip6addr_t router; /**< Router itself */ 00281 } fip_mydefrouter_t; 00282 00283 /** Scratchpad for IPv6 Fragmentation */ 00284 typedef struct 00285 { 00286 uint32_t fragId; /**< FragID of this packet */ 00287 unsigned int receivedBytes; /**< Received unfragmented size, used to detect end & overlapping */ 00288 unsigned int expectedBytes; /**< Expected unfragmented size */ 00289 unsigned int unfragmentSize; /**< Size of unfragmentable data */ 00290 unsigned char firstFrag : 1; /**< Offset = 0 fragment has been received */ 00291 unsigned char lastFrag : 1; /**< M = 0 fragment has been received */ 00292 uint8_t * nhPointer; /**< Pointer to the next header */ 00293 uint16_t expireTime16s; /**< When the fragment times out */ 00294 }fip_ip6frag_attr_t; 00295 00296 /** 00297 * @} fip_types 00298 */ 00299 00300 /* ################################## FIP MISC STUFF ########################## */ 00301 00302 /** Act on Configuration */ 00303 #if FIP_CONF_FIXED_LLADDR_LEN 00304 /* Fixed LL Address Length */ 00305 #define fip_ll_addrLenInvalid(x) (x != FIP_CONF_LLADDR_LEN) 00306 #else 00307 /* Variable LL Address Length */ 00308 #define fip_ll_addrLenInvalid(x) (x > FIP_CONF_LLADDR_LEN) 00309 #endif 00310 00311 /* ################################## FIP FUNCTIONS ########################### */ 00312 00313 /**** FIP Functions ****/ 00314 void fip_init(void); 00315 void fip_task(void); 00316 fip_bool_t fip_memcmp_ucharLen(const unsigned char * a, const unsigned char * b, unsigned char len); 00317 fip_bool_t fip_memcmp_uintLen(const unsigned char * a, const unsigned char * b, uint16_t len); 00318 unsigned char fip_memmatch_ucharLen(const unsigned char * a, const unsigned char * b, unsigned char len); 00319 void fip_memclr_ucharLen(unsigned char * dest, unsigned char length); 00320 fip_bool_t fip_ismemclr(const unsigned char * dest, unsigned char length); 00321 fip_return_t fip_ipUtils_generateAutoconfIID(unsigned char result[], const unsigned char llAddrPtr[], unsigned char llAddrLen); 00322 #include "fip_packet.h" 00323 #include "fip_nd6.h" 00324 #include "fip_sixlowpan.h" 00325 00326 /**** IF Functions ****/ 00327 #include "fip_if.h" 00328 00329 /**** IP Functions ****/ 00330 void fip_ip_process(void); 00331 void fip_ip_send(void); 00332 uint16_t fip_ipUtils_checksum(uint16_t startingValue, uint8_t data[], unsigned int number); 00333 uint16_t fip_ipUtils_checksum_tl(void); 00334 uint16_t fip_ipUtils_checksum_pseudo6hdr(uint16_t startingValue, uint8_t type); 00335 void fip_ipUtils_IP6toString(char * s, uint8_t * ipaddr); 00336 fip_return_t fip_ipUtils_stringToIP6(const char * s, uint8_t * ipaddr); 00337 fip_bool_t fip_isSrcUnspecified(void); 00338 fip_bool_t fip_isDestUnspecified(void); 00339 00340 #include "fip_route6.h" 00341 00342 /**** TCP Functions ****/ 00343 00344 /**** UDP Functions ****/ 00345 #include "fip_udp.h" 00346 00347 /**** ICMP Functions ****/ 00348 void fip_icmp6_process(void); 00349 fip_return_t fip_nd6_process(void); 00350 void fip_icmp6_finalize(void); 00351 void fip_icmp6_generateEchoRequest(fip_ifnum_t ifnum, fip_ip6addr_t * destAddr, unsigned int length); 00352 void fip_icmp6_generateError(uint8_t type, uint8_t code, uint32_t parameter); 00353 00354 /**** Link-Layer Functions Functions ****/ 00355 void 00356 fip_llgeneric_init(fip_ifnum_t ifnum, fip_llptraddr_t lladdr, char * name, void(*ifProcess)(void)); 00357 void fip_llgeneric_input(const uint8_t * srcAddr, 00358 unsigned char srcAddrLen, 00359 const uint8_t * destAddr, 00360 unsigned char destAddrLen, 00361 const uint8_t * data, 00362 unsigned int dataLen); 00363 00364 00365 /* ################################## HOST INTERFACE FUNCTIONS ########################### */ 00366 00367 /** 00368 * @addtogroup fip_hostInterface 00369 * @{ 00370 */ 00371 00372 /** 00373 * Host interface function. Get seconds since system boot in 32-bit unsigned integer. 00374 */ 00375 uint32_t fip_hostInterface_getSeconds32(void); 00376 00377 /** 00378 * Host interface function. Get seconds since system boot in 16-bit unsigned integer. 00379 */ 00380 uint16_t fip_hostInterface_getSeconds16(void); 00381 00382 /** 00383 * Host interface function. Get milliseconds since system boot in 32-bit unsigned integer. 00384 */ 00385 uint32_t fip_hostInterface_getMiliSeconds32(void); 00386 00387 /** 00388 * Host interface function. Get milliseconds since system boot in 16-bit unsigned integer. 00389 */ 00390 uint16_t fip_hostInterface_getMiliSeconds16(void); 00391 00392 /** 00393 * Host interface function. Get random number from hardware generator, used to 00394 * seed fip's pseudorandom generator. Returns a different value for each call 00395 * to this function, even when the program is restarted. Does not need to be 00396 * actually a random distribution, as it's only used as a seed for the PRNG. 00397 */ 00398 uint32_t fip_hostInterface_getRandom32(void); 00399 00400 /** 00401 * @} 00402 */ 00403 00404 00405 00406 #endif /* FIP_H_ */