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 _IPV6_H_
14 #define _IPV6_H_
15 
16 #include <stdint.h>
17 #include "ethernet.h"
18 
19 #define __IPV6_DEBUG__
20 
21 #ifdef __IPV6_DEBUG__
22 #define IPV6_DEBUG_PRINT(format, ...) do { printf(format, ## __VA_ARGS__); } while (0)
23 #else
24 #define IPV6_DEBUG_PRINT(format, ...)
25 #endif
26 
27 #define IPV6_ADDR_LENGTH	 16 /* Size of IPv6 adress in bytes */
28 #define IPV6_LL_PREFIX		 0xFE80000000000000ULL
29 #define IPV6_LL_PREFIX_MASK	 0xFFC0000000000000ULL
30 #define IPV6_SOLIC_NODE_PREFIX   0xFF02000000000000ULL
31 #define IPV6_SOLIC_NODE_IFACE_ID 0x00000001FF000000ULL
32 
33 /**
34  *  An IPv6 Address
35  */
36 typedef union {
37 	uint8_t addr[IPV6_ADDR_LENGTH];
38 	struct {
39 		uint64_t prefix;
40 		uint64_t interface_id;
41 	} part;
42 } ip6_addr_t;
43 
44 typedef struct {
45 	uint8_t type;
46 	uint8_t pad[7];
47 	union {
48 		ip6_addr_t  v6;
49 		char        v4[4];
50 	} addr;
51 } netaddr_t;
52 
53 /** \struct prefix_info
54  *
55  * List of Prefixes we have adresses from
56  * Used for internal purposes, information derived from prefix option
57  * in Router Advertisements
58  * See RFC 4861 section 4.6.2
59  */
60 struct prefix_info {
61 	uint64_t prefix;
62 	uint8_t  on_link:1,         /* When set prefix can be used for on-link
63                                      * determination */
64 		 autoconf:1,        /* Prefix can be used for stateless address
65                                      * configuration */
66 		 reserved1:6;
67 	uint32_t valid_lifetime;     /* Time until prefix expires */
68 	uint32_t preferred_lifetime; /* Time until prefix becomes deprecated */
69 	uint32_t start_time;         /* Time when received */
70 	uint32_t reserved2;
71 	struct   prefix_info *next;
72 };
73 
74 
75 /* List of IPv6 addresses */
76 struct ip6addr_list_entry {
77 	ip6_addr_t addr;
78 	struct prefix_info prfx_info;
79 	struct ip6addr_list_entry *next;
80 };
81 
82 /** \struct ip6hdr
83  *  A header for IPv6 packets.
84  *  For more information see RFC 2460
85  */
86 struct ip6hdr {
87 	uint32_t ver_tc_fl;	/**< Version, Traffic class, Flow label	*/
88 	uint16_t pl;		/**< Payload length			*/
89 	uint8_t  nh;		/**< Next header			*/
90 	uint8_t  hl;		/**< Hop limit				*/
91 	ip6_addr_t src;		/**< IPv6 source address		*/
92 	ip6_addr_t dst;		/**< IPv6 destination address		*/
93 } __attribute((packed));
94 
95 /** \struct packeth
96  * Struct with pointers to headers within a packet
97  */
98 struct packeth {
99 	struct ethhdr  *ethh;
100 	struct ip6hdr  *ip6h;
101 	struct icmp6hdr  *icmp6h;
102 	struct udphdr  *udph;
103 	/* ... */
104 };
105 
106 /** \struct parseip6_state
107  * Stores information about state of IPv6 address parser
108  */
109 struct parseip6_state {
110 	char *lookahead;
111 	char *ptr;
112 	const char *addr;
113 	int state;
114 	int s1ctr;
115 	int s2ctr;
116 	int blocknr;
117 	int zeroblocks;
118 	int i;
119 	int done;
120 	int errorcode;
121 };
122 
123 /** \struct ip6_config
124  * Stores flags wheter we use Stateless- or Stateful Autoconfiguration or DHCPv6
125  */
126 struct ip6_config {
127 	uint8_t managed_mode:1,
128 		other_config:1,
129 		reserved:6;
130 };
131 
132 /******************** VARIABLES **********************************************/
133 
134 extern struct ip6_config ip6_state;
135 
136 /******************** FUNCTIONS *********************************************/
137 /* Handles IPv6-packets that are detected by receive_ether. */
138 int8_t handle_ipv6(int fd, uint8_t * ip6_packet, uint32_t packetsize);
139 
140 /* Fill IPv6 header */
141 void fill_ip6hdr(uint8_t * packet, uint16_t packetsize,
142 	         uint8_t ip_proto, ip6_addr_t *ip6_src, ip6_addr_t *ip6_dst);
143 
144 /* Set own IPv6 address */
145 void set_ipv6_address(int fd, ip6_addr_t *own_ip6);
146 
147 /* Get own IPv6 address */
148 ip6_addr_t *get_ipv6_address(void);
149 
150 /* Create link-local address from a given Mac Address */
151 void ip6_create_ll_address (const uint8_t *own_mac, ip6_addr_t *ll_addr);
152 
153 /* For a given MAC calculates EUI64-Identifier.*/
154 uint64_t mac2eui64 (const uint8_t *mac);
155 
156 /* Create empty element for prefix list and return a pointer to it */
157 struct prefix_info * ip6_create_prefix_info(void);
158 
159 /* Create a new IPv6 address with a given network prefix
160  *	and add it to our IPv6 address list */
161 void * ip6_prefix2addr (ip6_addr_t prefix);
162 
163 /* Compare IPv6 adresses */
164 int8_t ip6_cmp(ip6_addr_t ip_1, ip6_addr_t ip_2);
165 
166 /* Check if it is a link-local address */
ip6_is_linklocal(ip6_addr_t * ip)167 static inline int ip6_is_linklocal(ip6_addr_t *ip)
168 {
169 	return (ip->part.prefix & IPV6_LL_PREFIX_MASK) == IPV6_LL_PREFIX;
170 }
171 
172 /* Check if prefix is already in our list */
173 int8_t unknown_prefix (ip6_addr_t *ip);
174 
175 /* Send IPv6 packet */
176 int send_ipv6 (int fd, void* buffer, int len);
177 
178 /* Add IPv6 address to list */
179 int8_t ip6addr_add (struct ip6addr_list_entry *new_address);
180 
181 /* Parse an IPv6 address */
182 int parseip6(const char *addr, uint8_t *parsedaddr);
183 int str_to_ipv6(const char *str, uint8_t *ip);
184 void ipv6_to_str(const uint8_t *ip, char *str);
185 
186 #endif
187