327 lines
9.9 KiB
C
327 lines
9.9 KiB
C
/*********************************************************************
|
|
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
|
|
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
|
|
|
|
.
|
|
|
|
*********************************************************************/
|
|
#ifndef _INCLUDE_PICO_ICMP6
|
|
#define _INCLUDE_PICO_ICMP6
|
|
#include "pico_addressing.h"
|
|
#include "pico_protocol.h"
|
|
#include "pico_mld.h"
|
|
/* ICMP header sizes */
|
|
#define PICO_ICMP6HDR_DRY_SIZE 4
|
|
#define PICO_ICMP6HDR_ECHO_REQUEST_SIZE 8
|
|
#define PICO_ICMP6HDR_DEST_UNREACH_SIZE 8
|
|
#define PICO_ICMP6HDR_TIME_XCEEDED_SIZE 8
|
|
#define PICO_ICMP6HDR_PARAM_PROBLEM_SIZE 8
|
|
#define PICO_ICMP6HDR_NEIGH_SOL_SIZE 24
|
|
#define PICO_ICMP6HDR_NEIGH_ADV_SIZE 24
|
|
#define PICO_ICMP6HDR_ROUTER_SOL_SIZE 8
|
|
#define PICO_ICMP6HDR_ROUTER_SOL_SIZE_6LP 16
|
|
#define PICO_ICMP6HDR_ROUTER_ADV_SIZE 16
|
|
#define PICO_ICMP6HDR_REDIRECT_SIZE 40
|
|
|
|
/* ICMP types */
|
|
#define PICO_ICMP6_DEST_UNREACH 1
|
|
#define PICO_ICMP6_PKT_TOO_BIG 2
|
|
#define PICO_ICMP6_TIME_EXCEEDED 3
|
|
#define PICO_ICMP6_PARAM_PROBLEM 4
|
|
#define PICO_ICMP6_ECHO_REQUEST 128
|
|
#define PICO_ICMP6_ECHO_REPLY 129
|
|
#define PICO_ICMP6_ROUTER_SOL 133
|
|
#define PICO_ICMP6_ROUTER_ADV 134
|
|
#define PICO_ICMP6_NEIGH_SOL 135
|
|
#define PICO_ICMP6_NEIGH_ADV 136
|
|
#define PICO_ICMP6_REDIRECT 137
|
|
|
|
/* destination unreachable codes */
|
|
#define PICO_ICMP6_UNREACH_NOROUTE 0
|
|
#define PICO_ICMP6_UNREACH_ADMIN 1
|
|
#define PICO_ICMP6_UNREACH_SRCSCOPE 2
|
|
#define PICO_ICMP6_UNREACH_ADDR 3
|
|
#define PICO_ICMP6_UNREACH_PORT 4
|
|
#define PICO_ICMP6_UNREACH_SRCFILTER 5
|
|
#define PICO_ICMP6_UNREACH_REJROUTE 6
|
|
|
|
/* time exceeded codes */
|
|
#define PICO_ICMP6_TIMXCEED_INTRANS 0
|
|
#define PICO_ICMP6_TIMXCEED_REASS 1
|
|
|
|
/* parameter problem codes */
|
|
#define PICO_ICMP6_PARAMPROB_HDRFIELD 0
|
|
#define PICO_ICMP6_PARAMPROB_NXTHDR 1
|
|
#define PICO_ICMP6_PARAMPROB_IPV6OPT 2
|
|
|
|
/* ping error codes */
|
|
#define PICO_PING6_ERR_REPLIED 0
|
|
#define PICO_PING6_ERR_TIMEOUT 1
|
|
#define PICO_PING6_ERR_UNREACH 2
|
|
#define PICO_PING6_ERR_ABORTED 3
|
|
#define PICO_PING6_ERR_PENDING 0xFFFF
|
|
|
|
/* ND configuration */
|
|
#define PICO_ND_MAX_FRAMES_QUEUED 4 /* max frames queued while awaiting address resolution */
|
|
|
|
/* ND RFC constants */
|
|
#define PICO_ND_MAX_SOLICIT 3
|
|
#define PICO_ND_MAX_NEIGHBOR_ADVERT 3
|
|
#define PICO_ND_DELAY_INCOMPLETE 1000 /* msec */
|
|
#define PICO_ND_DELAY_FIRST_PROBE_TIME 5000 /* msec */
|
|
|
|
/* neighbor discovery options */
|
|
#define PICO_ND_OPT_LLADDR_SRC 1
|
|
#define PICO_ND_OPT_LLADDR_TGT 2
|
|
#define PICO_ND_OPT_PREFIX 3
|
|
#define PICO_ND_OPT_REDIRECT 4
|
|
#define PICO_ND_OPT_MTU 5
|
|
#define PICO_ND_OPT_RDNSS 25 /* RFC 5006 */
|
|
#define PICO_ND_OPT_ARO 33 /* RFC 6775 */
|
|
#define PICO_ND_OPT_6CO 34 /* RFC 6775 */
|
|
#define PICO_ND_OPT_ABRO 35 /* RFC 6775 */
|
|
|
|
/* ND advertisement flags */
|
|
#define PICO_ND_ROUTER 0x80000000
|
|
#define PICO_ND_SOLICITED 0x40000000
|
|
#define PICO_ND_OVERRIDE 0x20000000
|
|
#define IS_ROUTER(x) (long_be(x->msg.info.neigh_adv.rsor) & (PICO_ND_ROUTER)) /* router flag set? */
|
|
#define IS_SOLICITED(x) (long_be(x->msg.info.neigh_adv.rsor) & (PICO_ND_SOLICITED)) /* solicited flag set? */
|
|
#define IS_OVERRIDE(x) (long_be(x->msg.info.neigh_adv.rsor) & (PICO_ND_OVERRIDE)) /* override flag set? */
|
|
|
|
#define PICO_ND_PREFIX_LIFETIME_INF 0xFFFFFFFFu
|
|
/* #define PICO_ND_DESTINATION_LRU_TIME 600000u / * msecs (10min) * / */
|
|
|
|
/* custom defines */
|
|
#define PICO_ICMP6_ND_UNICAST 0
|
|
#define PICO_ICMP6_ND_ANYCAST 1
|
|
#define PICO_ICMP6_ND_SOLICITED 2
|
|
#define PICO_ICMP6_ND_DAD 3
|
|
#define PICO_ICMP6_ND_DEREGISTER 4
|
|
|
|
#define PICO_ICMP6_MAX_RTR_SOL_DELAY 1000
|
|
|
|
#define PICO_ICMP6_OPT_LLADDR_SIZE (8)
|
|
|
|
/******************************************************************************
|
|
* 6LoWPAN Constants
|
|
******************************************************************************/
|
|
|
|
/* Address registration lifetime */
|
|
#define PICO_6LP_ND_DEFAULT_LIFETIME (120) /* TWO HOURS */
|
|
|
|
extern struct pico_protocol pico_proto_icmp6;
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_hdr {
|
|
uint8_t type;
|
|
uint8_t code;
|
|
uint16_t crc;
|
|
|
|
PACKED_UNION_DEF icmp6_msg_u {
|
|
/* error messages */
|
|
PACKED_UNION_DEF icmp6_err_u {
|
|
PEDANTIC_STRUCT_DEF dest_unreach_s {
|
|
uint32_t unused;
|
|
} dest_unreach;
|
|
PEDANTIC_STRUCT_DEF pkt_too_big_s {
|
|
uint32_t mtu;
|
|
} pkt_too_big;
|
|
PEDANTIC_STRUCT_DEF time_exceeded_s {
|
|
uint32_t unused;
|
|
} time_exceeded;
|
|
PEDANTIC_STRUCT_DEF param_problem_s {
|
|
uint32_t ptr;
|
|
} param_problem;
|
|
} err;
|
|
|
|
/* informational messages */
|
|
PACKED_UNION_DEF icmp6_info_u {
|
|
PEDANTIC_STRUCT_DEF echo_request_s {
|
|
uint16_t id;
|
|
uint16_t seq;
|
|
} echo_request;
|
|
PEDANTIC_STRUCT_DEF echo_reply_s {
|
|
uint16_t id;
|
|
uint16_t seq;
|
|
} echo_reply;
|
|
PEDANTIC_STRUCT_DEF router_sol_s {
|
|
uint32_t unused;
|
|
} router_sol;
|
|
PEDANTIC_STRUCT_DEF router_adv_s {
|
|
uint8_t hop;
|
|
uint8_t mor;
|
|
uint16_t life_time;
|
|
uint32_t reachable_time;
|
|
uint32_t retrans_time;
|
|
} router_adv;
|
|
PEDANTIC_STRUCT_DEF neigh_sol_s {
|
|
uint32_t unused;
|
|
struct pico_ip6 target;
|
|
} neigh_sol;
|
|
PEDANTIC_STRUCT_DEF neigh_adv_s {
|
|
uint32_t rsor;
|
|
struct pico_ip6 target;
|
|
} neigh_adv;
|
|
PEDANTIC_STRUCT_DEF redirect_s {
|
|
uint32_t reserved;
|
|
struct pico_ip6 target;
|
|
struct pico_ip6 dest;
|
|
} redirect;
|
|
PEDANTIC_STRUCT_DEF mld_s {
|
|
uint16_t max_resp_time;
|
|
uint16_t reserved;
|
|
struct pico_ip6 mmcast_group;
|
|
/*MLDv2*/
|
|
uint8_t reserverd; /* With S and QRV */
|
|
uint8_t QQIC;
|
|
uint16_t nbr_src;
|
|
struct pico_ip6 src[1];
|
|
} mld;
|
|
/* 6LoWPAN Duplicate Address Message */
|
|
PEDANTIC_STRUCT_DEF da_s {
|
|
uint8_t status;
|
|
uint8_t reserved;
|
|
uint16_t lifetime;
|
|
struct pico_6lowpan_ext eui64;
|
|
struct pico_ip6 addr;
|
|
} da;
|
|
} info;
|
|
} msg;
|
|
};
|
|
|
|
PACKED_UNION_DEF pico_hw_addr {
|
|
struct pico_eth mac;
|
|
#ifdef PICO_SUPPORT_6LOWPAN
|
|
union pico_6lowpan_u pan;
|
|
#endif /* PICO_SUPPORT_6LOWPAN */
|
|
uint8_t data[8];
|
|
};
|
|
|
|
/******************************************************************************
|
|
* ICMP6 Neighbor Discovery Options
|
|
******************************************************************************/
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_lladdr
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
union pico_hw_addr addr;
|
|
};
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_prefix
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint8_t prefix_len;
|
|
uint8_t res : 6;
|
|
uint8_t aac : 1;
|
|
uint8_t onlink : 1;
|
|
uint32_t val_lifetime;
|
|
uint32_t pref_lifetime;
|
|
uint32_t reserved;
|
|
struct pico_ip6 prefix;
|
|
};
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_mtu
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint16_t res;
|
|
uint32_t mtu;
|
|
};
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_redirect
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint16_t res0;
|
|
uint32_t res1;
|
|
};
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_rdnss
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint16_t res0;
|
|
uint32_t lifetime;
|
|
struct pico_ip6 *addr;
|
|
};
|
|
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_na
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
};
|
|
|
|
/* 6LoWPAN Address Registration Option (ARO) */
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_aro
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint8_t status;
|
|
uint8_t res0;
|
|
uint16_t res1;
|
|
uint16_t lifetime;
|
|
struct pico_6lowpan_ext eui64;
|
|
};
|
|
|
|
#define ICMP6_ARO_SUCCES (0u)
|
|
#define ICMP6_ARO_DUP (1u)
|
|
#define ICMP6_ARO_FULL (2u)
|
|
|
|
/* 6LoWPAN Context Option (6CO) */
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_6co
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint8_t clen;
|
|
uint8_t id: 4;
|
|
uint8_t res: 3;
|
|
uint8_t c: 1;
|
|
uint16_t lifetime;
|
|
uint8_t prefix;
|
|
};
|
|
|
|
/* 6LoWPAN Authoritative Border Router Option (ABRO) */
|
|
PACKED_STRUCT_DEF pico_icmp6_opt_abro
|
|
{
|
|
uint8_t type;
|
|
uint8_t len;
|
|
uint16_t version_low;
|
|
uint16_t version_high;
|
|
uint16_t lifetime;
|
|
struct pico_ip6 addr;
|
|
};
|
|
|
|
struct pico_icmp6_stats
|
|
{
|
|
unsigned long size;
|
|
unsigned long seq;
|
|
pico_time time;
|
|
unsigned long ttl;
|
|
int err;
|
|
struct pico_ip6 dst;
|
|
};
|
|
|
|
int pico_icmp6_ping(char *dst, int count, int interval, int timeout, int size, void (*cb)(struct pico_icmp6_stats *), struct pico_device *dev);
|
|
int pico_icmp6_ping_abort(int id);
|
|
|
|
|
|
int pico_icmp6_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *tgt, uint8_t type, struct pico_ip6 *dst);
|
|
int pico_icmp6_neighbor_advertisement(struct pico_frame *f, struct pico_ip6 *target);
|
|
int pico_icmp6_router_solicitation(struct pico_device *dev, struct pico_ip6 *src, struct pico_ip6 *dst);
|
|
|
|
int pico_icmp6_port_unreachable(struct pico_frame *f);
|
|
int pico_icmp6_proto_unreachable(struct pico_frame *f);
|
|
int pico_icmp6_dest_unreachable(struct pico_frame *f);
|
|
int pico_icmp6_ttl_expired(struct pico_frame *f);
|
|
int pico_icmp6_packet_filtered(struct pico_frame *f);
|
|
int pico_icmp6_parameter_problem(struct pico_frame *f, uint8_t problem, uint32_t ptr);
|
|
int pico_icmp6_pkt_too_big(struct pico_frame *f);
|
|
int pico_icmp6_frag_expired(struct pico_frame *f);
|
|
|
|
uint16_t pico_icmp6_checksum(struct pico_frame *f);
|
|
int pico_icmp6_router_advertisement(struct pico_device *dev, struct pico_ip6 *dst);
|
|
|
|
#endif
|