📄 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"
#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -