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 #include <stdlib.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include "ipv6.h"
17 #include "icmpv6.h"
18 #include "ndp.h"
19
20 /* Neighbor cache */
21 static struct neighbor *first_neighbor;
22 static struct neighbor *last_neighbor;
23
24 /* Router list */
25 static struct router *first_router;
26 static struct router *last_router;
27
28 /*
29 * NET: add new router to list
30 * @param struct router nghb - new router
31 * @return true or false
32 */
33 int8_t
router_add(struct router * nghb)34 router_add (struct router *nghb )
35 {
36 if (nghb == NULL)
37 return -1;
38
39 if (first_router == NULL) {
40 first_router= nghb;
41 last_router = first_router;
42 last_router->next = NULL;
43 } else {
44 last_router->next = nghb;
45 last_router = nghb;
46 last_router->next = NULL;
47 }
48 return 1; /* no error */
49 }
50
51 /*
52 * NET: create a new router
53 * @param uint8_t *packet - received packet (Ethernet/IPv6/ICMPv6/ND_NghSlct)
54 * @param struct packeth - pointers to headers in packet
55 * @return pointer to new router
56 */
57 void *
router_create(uint8_t * mac,ip6_addr_t ip)58 router_create(uint8_t *mac, ip6_addr_t ip)
59 {
60 struct router *new_router;
61
62 new_router = malloc (sizeof(struct router));
63 if( !new_router) {
64 return 0;
65 }
66 memset (new_router, 0, sizeof(struct router));
67
68 /* fill neighbor struct */
69 memcpy (new_router->mac, mac, 6);
70 memcpy (&(new_router->ip.addr[0]), ip.addr, IPV6_ADDR_LENGTH);
71
72 return new_router;
73 }
74
75 struct router *
find_router(ip6_addr_t ip)76 find_router(ip6_addr_t ip)
77 {
78 struct router *n = NULL;
79
80 for (n = first_router; n != NULL ; n=n->next)
81 if (ip6_cmp(n->ip, ip))
82 return n; /* router is already in list*/
83
84 return NULL; /* router is unknown */
85 }
86
87 /**
88 * Find a router for a given host address
89 * @param ip - IPv6 address with the prefered prefix
90 * @return pointer to router, or NULL if none is available
91 */
ipv6_get_default_router(ip6_addr_t ip)92 struct router *ipv6_get_default_router(ip6_addr_t ip)
93 {
94 struct router *n = NULL;
95
96 for (n = first_router; n != NULL; n = n->next) {
97 if (n->ip.part.prefix == ip.part.prefix)
98 return n;
99 }
100
101 return first_router;
102 }
103
104 /*
105 * NET: add new neighbor to list
106 * @param struct neighbor nghb - new neighbor
107 * @return true or false
108 */
109 int8_t
neighbor_add(struct neighbor * nghb)110 neighbor_add (struct neighbor *nghb)
111 {
112 if (nghb == NULL)
113 return -1;
114
115 if (first_neighbor == NULL) {
116 first_neighbor = nghb;
117 last_neighbor = first_neighbor;
118 last_neighbor->next = NULL;
119 } else {
120 last_neighbor->next = nghb;
121 last_neighbor = nghb;
122 last_neighbor->next = NULL;
123 }
124
125 return 1; /* no error */
126 }
127
128 /*
129 * NET: create a new neighbor
130 * @param uint8_t *packet - received packet (Ethernet/IPv6/ICMPv6/ND_NghSlct)
131 * @param struct packeth - pointers to headers in packet
132 * @return pointer - pointer to new neighbor
133 * NULL - malloc failed
134 */
135 void *
neighbor_create(uint8_t * packet,struct packeth * headers)136 neighbor_create (uint8_t *packet, struct packeth *headers)
137 {
138 struct neighbor *new_neighbor;
139
140 new_neighbor = malloc (sizeof(struct neighbor));
141 if( !new_neighbor )
142 return NULL;
143 memset(new_neighbor, 0, sizeof(struct neighbor));
144
145 /* fill neighbor struct */
146 memcpy (&(new_neighbor->mac),
147 &(headers->ethh->src_mac[0]), 6);
148 memcpy (&(new_neighbor->ip.addr), &(headers->ip6h->src), IPV6_ADDR_LENGTH);
149 new_neighbor->status = NB_INCOMPLETE;
150
151 return new_neighbor;
152 }
153
154 /**
155 * NET: Find neighbor with given IPv6 address in Neighbor Cache
156 *
157 * @param ip - Pointer to IPv6 address
158 * @return pointer - pointer to client IPv6 address (e.g. ::1)
159 * NULL - Neighbor not found
160 */
161 struct neighbor *
find_neighbor(ip6_addr_t ip)162 find_neighbor(ip6_addr_t ip)
163 {
164 struct neighbor *n = NULL;
165
166 for (n = first_neighbor; n != NULL ; n=n->next) {
167 if (ip6_cmp(n->ip, ip)) {
168 return n; /* neighbor is already in cache */
169 }
170 }
171
172 return NULL; /* neighbor is unknown */
173 }
174
ndp_init(void)175 void ndp_init(void)
176 {
177 /* Router list */
178 first_router = NULL;
179 last_router = first_router;
180
181 /* Init Neighbour cache */
182 first_neighbor = NULL;
183 last_neighbor = first_neighbor;
184 }
185