blob: 07deb731f1bf13ee27536cbd15449a593ac1dc5d [file] [log] [blame]
/*
* ppp_platform.h -- platform specific header file
*
* (C) Copyright [2006-2008] Marvell International Ltd.
* All Rights Reserved
*
*/
#ifndef __PPP_IPV6_LINUX_H__
#define __PPP_IPV6_LINUX_H__
#if defined __cplusplus /* __cplusplus */
extern "C" {
#endif
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdint.h>
#include <signal.h>
#include <time.h>
#include "pxa_dbg.h"
#include <linux/ip.h>
//#include <linux/ipv6.h>
#define IP6_HLEN 40
#define IP6_NEXTH_HOPBYHOP 0
#define IP6_NEXTH_TCP 6
#define IP6_NEXTH_UDP 17
#define IP6_NEXTH_ENCAPS 41
#define IP6_NEXTH_ROUTING 43
#define IP6_NEXTH_FRAGMENT 44
#define IP6_NEXTH_ESP 50
#define IP6_NEXTH_AH 51
#define IP6_NEXTH_ICMP6 58
#define IP6_NEXTH_NONE 59
#define IP6_NEXTH_DESTOPTS 60
#define IP6_NEXTH_UDPLITE 136
#define IP6_FRAG_INFO_BACKUP_LEN 20
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
struct ip6_addr {
u32_t addr[4];
};
typedef struct ip6_addr ip6_addr_t;
typedef struct ip6_addr ip6_addr_p_t;
/* The IPv6 header. */
struct ip6_hdr {
/* version / traffic class / flow label */
u32_t _v_tc_fl;
/* payload length */
u16_t _plen;
/* next header */
u8_t _nexth;
/* hop limit */
u8_t _hoplim;
/* source and destination IP addresses */
ip6_addr_p_t src;
ip6_addr_p_t dest;
}__attribute__((packed));
#define IP6H_V(hdr) ((ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f)
#define IP6H_TC(hdr) ((ntohl((hdr)->_v_tc_fl) >> 20) & 0xff)
#define IP6H_FL(hdr) (ntohl((hdr)->_v_tc_fl) & 0x000fffff)
#define IP6H_PLEN(hdr) (ntohs((hdr)->_plen))
#define IP6H_NEXTH(hdr) ((hdr)->_nexth)
#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6)
#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim)
#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (htonl(((v) << 28) | ((tc) << 20) | (fl)))
#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = htons(plen)
#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth)
#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl)
#define NETIF_MAX_HWADDR_LEN 6
#define RA_MSG_LEN 256
#define DHCPV6_MSG_LEN 1024
enum icmp6_type {
ICMP6_TYPE_DUR = 1, /* Destination unreachable */
ICMP6_TYPE_PTB = 2, /* Packet too big */
ICMP6_TYPE_TE = 3, /* Time exceeded */
ICMP6_TYPE_PP = 4, /* Parameter problem */
ICMP6_TYPE_PE1 = 100, /* Private experimentation */
ICMP6_TYPE_PE2 = 101, /* Private experimentation */
ICMP6_TYPE_RSV_ERR = 127, /* Reserved for expansion of error messages */
ICMP6_TYPE_EREQ = 128, /* Echo request */
ICMP6_TYPE_EREP = 129, /* Echo reply */
ICMP6_TYPE_MLQ = 130, /* Multicast listener query */
ICMP6_TYPE_MLR = 131, /* Multicast listener report */
ICMP6_TYPE_MLD = 132, /* Multicast listener done */
ICMP6_TYPE_RS = 133, /* Router solicitation */
ICMP6_TYPE_RA = 134, /* Router advertisement */
ICMP6_TYPE_NS = 135, /* Neighbor solicitation */
ICMP6_TYPE_NA = 136, /* Neighbor advertisement */
ICMP6_TYPE_RD = 137, /* Redirect */
ICMP6_TYPE_MRA = 151, /* Multicast router advertisement */
ICMP6_TYPE_MRS = 152, /* Multicast router solicitation */
ICMP6_TYPE_MRT = 153, /* Multicast router termination */
ICMP6_TYPE_PE3 = 200, /* Private experimentation */
ICMP6_TYPE_PE4 = 201, /* Private experimentation */
ICMP6_TYPE_RSV_INF = 255 /* Reserved for expansion of informational messages */
};
/** Access address in 16-bit block */
#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0]) >> 16) & 0xffff)
#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0])) & 0xffff)
#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1]) >> 16) & 0xffff)
#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1])) & 0xffff)
#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2]) >> 16) & 0xffff)
#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2])) & 0xffff)
#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3]) >> 16) & 0xffff)
#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3])) & 0xffff)
#define ip6_addr_debug_print(fmt, ipaddr) \
ERRMSG(fmt" %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", \
IP6_ADDR_BLOCK1(ipaddr) , \
IP6_ADDR_BLOCK2(ipaddr) , \
IP6_ADDR_BLOCK3(ipaddr), \
IP6_ADDR_BLOCK4(ipaddr), \
IP6_ADDR_BLOCK5(ipaddr), \
IP6_ADDR_BLOCK6(ipaddr), \
IP6_ADDR_BLOCK7(ipaddr), \
IP6_ADDR_BLOCK8(ipaddr))
#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).in6_u.u6_addr32[0]; \
(dest).addr[1] = (src).in6_u.u6_addr32[1]; \
(dest).addr[2] = (src).in6_u.u6_addr32[2]; \
(dest).addr[3] = (src).in6_u.u6_addr32[3];}while(0)
#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & 0xff) << 24) | \
(((x) & 0xff00) << 8) | \
(((x) & 0xff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL))
#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff010000UL))
#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff020000UL))
#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL))
#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL))
#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || \
((ip6addr)->addr[0] == 0UL) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == 0UL))
#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
#define ip6_addr_isglobal(ip6addr) (!ip6_addr_isany(ip6addr) && \
!ip6_addr_islinklocal(ip6addr) && \
!ip6_addr_issitelocal(ip6addr) && \
!ip6_addr_isloopback(ip6addr) && \
!ip6_addr_ismulticast(ip6addr))
#define ip6_addr_is_dns_server(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xfec00000UL)) && \
((ip6addr)->addr[1] == PP_HTONL(0x0000ffffUL)) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0)
#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00000002UL)))
#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0)
/* FF02::1:2 */
#define ip6_addr_is_dhcp_agentserver(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00010002UL)))
/* FF05::1:3 */
#define ip6_addr_is_dhcp_allserver(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff050000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
((ip6addr)->addr[3] == PP_HTONL(0x00010003UL)))
#define ip6_addr_is_same(src,dst) (((src)->addr[0] == (dst)->addr[0]) && \
((src)->addr[1] == (dst)->addr[1]) && \
((src)->addr[2] == (dst)->addr[2]) && \
((src)->addr[3] == (dst)->addr[3]))
#define ip6_interface_addr_is_same(src,dst) (((src)->addr[2] == (dst)->addr[2]) && \
((src)->addr[3] == (dst)->addr[3] + 1))
/** Safely copy one IPv6 address to another (src may be NULL) */
#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
(dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
(dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
(dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0)
/** Safely copy one IPv6 address to another (src may be NULL) */
#define ip6_addr_set_turn(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : PP_HTONL((src)->addr[0]); \
(dest)->addr[1] = (src) == NULL ? 0 : PP_HTONL((src)->addr[1]); \
(dest)->addr[2] = (src) == NULL ? 0 : PP_HTONL((src)->addr[2]); \
(dest)->addr[3] = (src) == NULL ? 0 : PP_HTONL((src)->addr[3]);}while(0)
/** Set complete address to zero */
#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = 0;}while(0)
/** Split an u32_t in two u16_ts and add them up */
#ifndef FOLD_U32T
#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL))
#endif
typedef u32_t mem_ptr_t;
/* ND definations */
/** Neighbor solicitation message header. */
struct ns_header {
u8_t type;
u8_t code;
u16_t chksum;
u32_t reserved;
ip6_addr_p_t target_address;
/* Options follow. */
} __attribute__((packed));
/** Neighbor advertisement message header. */
struct na_header {
u8_t type;
u8_t code;
u16_t chksum;
u8_t flags;
u8_t reserved[3];
ip6_addr_p_t target_address;
/* Options follow. */
}__attribute__((packed));
#define ND6_FLAG_ROUTER (0x80)
#define ND6_FLAG_SOLICITED (0x40)
#define ND6_FLAG_OVERRIDE (0x20)
/** Router solicitation message header. */
struct rs_header {
u8_t type;
u8_t code;
u16_t chksum;
u32_t reserved;
/* Options follow. */
}__attribute__((packed));
/** Router advertisement message header. */
#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80)
#define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40)
#define ND6_RA_FLAG_HOME_AGENT (0x20)
#define ND6_RA_PREFERENCE_MASK (0x18)
#define ND6_RA_PREFERENCE_HIGH (0x08)
#define ND6_RA_PREFERENCE_MEDIUM (0x00)
#define ND6_RA_PREFERENCE_LOW (0x18)
#define ND6_RA_PREFERENCE_DISABLED (0x10)
struct ra_header {
u8_t type;
u8_t code;
u16_t chksum;
u8_t current_hop_limit;
u8_t flags;
u16_t router_lifetime;
u32_t reachable_time;
u32_t retrans_timer;
/* Options follow. */
}__attribute__((packed));
/** Redirect message header. */
struct redirect_header {
u8_t type;
u8_t code;
u16_t chksum;
u32_t reserved;
ip6_addr_p_t target_address;
ip6_addr_p_t destination_address;
/* Options follow. */
}__attribute__((packed));
/** Link-layer address option. */
#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01)
#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02)
struct lladdr_option {
u8_t type;
u8_t length;
u8_t addr[NETIF_MAX_HWADDR_LEN];
} __attribute__((packed));
/** Prefix information option. */
#define ND6_OPTION_TYPE_PREFIX_INFO (0x03)
#define ND6_PREFIX_FLAG_ON_LINK (0x80)
#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40)
#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20)
#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10)
struct prefix_option {
u8_t type;
u8_t length;
u8_t prefix_length;
u8_t flags;
u32_t valid_lifetime;
u32_t preferred_lifetime;
u8_t reserved2[3];
u8_t site_prefix_length;
ip6_addr_p_t prefix;
}__attribute__((packed));
#define ND6_OPTION_TYPE_DNS (0x19)
struct dns_svr_option { //rfc 4339 & rfc 61016
u8_t type;
u8_t length;
u16_t reserved;
u32_t lifetime;
u32_t dns1[4];
u32_t dns2[4];
} __attribute__((packed));
/** Redirected header option. */
#define ND6_OPTION_TYPE_REDIR_HDR (0x04)
struct redirected_header_option {
u8_t type;
u8_t length;
u8_t reserved[6];
/* Portion of redirected packet follows. */
/* PACK_STRUCT_FIELD(u8_t redirected[8]); */
} __attribute__((packed));
/** MTU option. */
#define ND6_OPTION_TYPE_MTU (0x05)
struct mtu_option {
u8_t type;
u8_t length;
u16_t reserved;
u32_t mtu;
}__attribute__((packed));
/** Route information option. */
#define ND6_OPTION_TYPE_ROUTE_INFO (24)
struct route_option {
u8_t type;
u8_t length;
u8_t prefix_length;
u8_t preference;
u32_t route_lifetime;
ip6_addr_p_t prefix;
} __attribute__((packed));
#define DHCP6_CLIENT_LEN 64
#define DHCP6_CLIENT_PORT 546
#define DHCP6_SERVER_PORT 547
#define DHCPV6_SOLICIT 1
#define DHCPV6_ADVERTISE 2
#define DHCPV6_REQUEST 3
#define DHCPV6_CONFIRM 4
#define DHCPV6_RENEW 5
#define DHCPV6_REBIND 6
#define DHCPV6_REPLY 7
#define DHCPV6_INFO_REQUEST 11
typedef struct _dhcpv6_packet
{
u8_t type;
u8_t xxid[3];
u32_t opts[1];
}__attribute__((packed)) dhcpv6_packet;
typedef struct _dhcpv6_opts
{
u16_t type;
u16_t size;
}__attribute__((packed)) dhcpv6_opts;
typedef struct _dhcpv6_opt_xid
{
u16_t type; // 1 for cid, 2 for sid
u16_t size; // 14
u16_t duid; // 1
u16_t hdwr; // 1 for Ethernet, 6 for IEEE 802, network order
u32_t time; // time stamp, network order
u8_t mac[6]; // mac address
}__attribute__((packed)) dhcpv6_opt_xid;
typedef struct _dhcpv6_opt_dns_svr
{
u16_t type; // 23
u16_t size; // 32
u32_t dns1[4]; // dns server 1
u32_t dns2[4]; // dns server 2
}__attribute__((packed)) dhcpv6_opt_dns_svr;
typedef struct _dhcpv6_packet_svr
{
u8_t ip_hdr[IP6_HLEN];
u8_t udp_hdr[8]; // reserved buffer for UDP header
u8_t type;
u8_t xxid[3];
u8_t opts[512];
}__attribute__((packed)) dhcpv6_packet_svr;
struct icmp6_hdr {
u8_t type;
u8_t code;
u16_t chksum;
u32_t data;
}__attribute__((packed));
struct udp_hdr {
u16_t src;
u16_t dest; /* src/dest UDP ports */
u16_t len;
u16_t chksum;
}__attribute__((packed));
enum PPP_ND_STATE {
ND_STATE_INIT,
ND_STATE_RS_SEND,
ND_STATE_RA_RECV,
ND_STATE_RA_SEND,
ND_STATE_DHCP_SEND,
ND_STATE_DATA_READY
};
void raValidPeriodTimerHandler(int sig UNUSED, siginfo_t *si UNUSED, void *uc UNUSED);
#if defined __cplusplus
}
#endif /* __cplusplus */
#endif