1 /******************************************************************************
2  * Copyright (c) 2013 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 
13 #ifndef _ICMPV6_H_
14 #define _ICMPV6_H_
15 
16 #include <stdint.h>
17 #include "ethernet.h"
18 #include "ipv6.h"
19 
20 #define __ICMPV6_DEBUG__
21 
22 #ifdef __ICMPV6_DEBUG__
23 #define ICMPV6_DEBUG_PRINT(format, ...) printf(format, ## __VA_ARGS__)
24 #else
25 #define ICMPV6_DEBUG_PRINT(format, ...)
26 #endif
27 
28 #define ICMPv6_HEADER_SIZE		4	/* Size of common fields */
29 #define IPTYPE_ICMPV6		     0x3a
30 
31 /* Error message types */
32 #define ICMPV6_DEST_UNREACHABLE		1	/* Destination unreachable */
33 #define ICMPV6_PACKET_TOO_BIG		2	/* Packet too big */
34 #define ICMPV6_TIME_EXCEEDED		3	/* Time exceeded */
35 #define ICMPV6_PARAM_PROBLEM		4	/* Parameter problem */
36 
37 /* Informational message types */
38 #define ICMPV6_ECHO_REQUEST		128	/* Echo request */
39 #define ICMPV6_ECHO_REPLY		129	/* Echo reply */
40 #define ICMPV6_MCAST_LISTENER_QUERY	130	/* Multicast listener query */
41 #define ICMPV6_MCAST_LISTENER_REPORT	131	/* Multicast listener report */
42 #define ICMPv6 MCAST_LISTENER_DONE	132	/* Multicast listener done */
43 #define ICMPV6_ROUTER_SOLICITATION	133	/* Router solicitation */
44 #define ICMPV6_ROUTER_ADVERTISEMENT	134	/* Router advertisement */
45 #define ICMPV6_NEIGHBOUR_SOLICITATION	135	/* Neighbor solicitation */
46 #define ICMPV6_NEIGHBOUR_ADVERTISEMENT	136	/* Neighbor advertisement */
47 #define ICMPV6_REDIRECT_MSG		137	/* Redirect message */
48 
49 /******** Functions *******************/
50 int8_t handle_icmpv6 (int fd, struct ethhdr *etherhdr, uint8_t  *ip6_packet);
51 void   send_neighbour_solicitation(int fd, ip6_addr_t *target_ip6);
52 void   send_router_solicitation(int fd);
53 int    is_ra_received(void);
54 
55 /* Prefix information */
56 struct option_prefix {
57 	uint8_t  type;
58 	uint8_t  length;
59 	uint8_t  prefix_length;
60 	uint8_t  onlink:1,
61 		 autom:1,
62 		 not_router:1,
63 		 not_site_prefix:1,
64 		 reserved:4;
65 	uint32_t valid_lifetime;
66 	uint32_t preferred_lifetime;
67 	uint32_t reserved2;
68 	ip6_addr_t prefix;
69 } __attribute((packed));
70 
71 /* Neighbour advertisement/solicitation flags */
72 struct na_flags {
73     uint8_t is_router:1,	/* sender (we) is a router */
74 	    na_is_solicited:1,	/* this NA was solicited (asked for) */
75 	    override:1,		/* receiver shall override its cache entries */
76 	    unused:5;
77 }__attribute((packed));
78 
79 /* Source/Target Link-layer address */
80 struct option_ll_address{
81         uint8_t  type;
82         uint8_t  length;
83         uint8_t  mac[ETH_ALEN];
84 } __attribute((packed));
85 
86 struct neighbour_solicitation {
87 	uint32_t router:1,
88 		 solicited:1,
89 		 override:1,
90 		 reserved:29;
91 	ip6_addr_t target;
92 	struct option_ll_address lladdr;
93 } __attribute((packed));
94 
95 struct neighbour_advertisement {
96 	uint32_t router:1,
97 		 solicited:1,
98 		 override:1,
99 		 reserved:29;
100 	ip6_addr_t target;
101 	struct option_ll_address lladdr;
102 } __attribute((packed));
103 
104 struct router_solicitation {
105 	uint32_t reserved;
106 	struct option_ll_address lladdr;
107 } __attribute((packed));
108 
109 struct router_advertisement {
110 	uint8_t curr_hop_limit;
111 	struct raflags {
112 		uint8_t managed:1,
113 			other:1,
114 			reserved:6;
115 	} flags;
116 	uint16_t router_lifetime;
117 	uint32_t reachable_time;
118 	uint32_t retrans_timer;
119 	struct option_prefix prefix;
120 	struct option_ll_address ll_addr;
121 } __attribute((packed));
122 
123 struct icmp6hdr {
124 	uint8_t type;
125 	uint8_t code;
126 	uint16_t checksum;
127 	union {
128 		struct neighbour_solicitation nghb_solicit;
129 		struct neighbour_advertisement nghb_adv;
130 		struct router_solicitation router_solicit;
131 		struct router_advertisement ra;
132 	} icmp6body;
133 } __attribute((packed));
134 
135 #endif
136