| /* |
| * 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 |