| /****************************************************************************** |
| * Copyright (c) 2013 IBM Corporation |
| * All rights reserved. |
| * This program and the accompanying materials |
| * are made available under the terms of the BSD License |
| * which accompanies this distribution, and is available at |
| * http://www.opensource.org/licenses/bsd-license.php |
| * |
| * Contributors: |
| * IBM Corporation - initial implementation |
| *****************************************************************************/ |
| |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include "ipv6.h" |
| #include "icmpv6.h" |
| #include "ndp.h" |
| |
| /* Neighbor cache */ |
| static struct neighbor *first_neighbor; |
| static struct neighbor *last_neighbor; |
| |
| /* Router list */ |
| static struct router *first_router; |
| static struct router *last_router; |
| |
| /* |
| * NET: add new router to list |
| * @param struct router nghb - new router |
| * @return true or false |
| */ |
| int8_t |
| router_add (struct router *nghb ) |
| { |
| if (nghb == NULL) |
| return -1; |
| |
| if (first_router == NULL) { |
| first_router= nghb; |
| last_router = first_router; |
| last_router->next = NULL; |
| } else { |
| last_router->next = nghb; |
| last_router = nghb; |
| last_router->next = NULL; |
| } |
| return 1; /* no error */ |
| } |
| |
| /* |
| * NET: create a new router |
| * @param uint8_t *packet - received packet (Ethernet/IPv6/ICMPv6/ND_NghSlct) |
| * @param struct packeth - pointers to headers in packet |
| * @return pointer to new router |
| */ |
| void * |
| router_create(uint8_t *mac, ip6_addr_t ip) |
| { |
| struct router *new_router; |
| |
| new_router = malloc (sizeof(struct router)); |
| if( !new_router) { |
| return 0; |
| } |
| memset (new_router, 0, sizeof(struct router)); |
| |
| /* fill neighbor struct */ |
| memcpy (new_router->mac, mac, 6); |
| memcpy (&(new_router->ip.addr[0]), ip.addr, IPV6_ADDR_LENGTH); |
| |
| return new_router; |
| } |
| |
| struct router * |
| find_router(ip6_addr_t ip) |
| { |
| struct router *n = NULL; |
| |
| for (n = first_router; n != NULL ; n=n->next) |
| if (ip6_cmp(n->ip, ip)) |
| return n; /* router is already in list*/ |
| |
| return NULL; /* router is unknown */ |
| } |
| |
| /** |
| * Find a router for a given host address |
| * @param ip - IPv6 address with the prefered prefix |
| * @return pointer to router, or NULL if none is available |
| */ |
| struct router *ipv6_get_default_router(ip6_addr_t ip) |
| { |
| struct router *n = NULL; |
| |
| for (n = first_router; n != NULL; n = n->next) { |
| if (n->ip.part.prefix == ip.part.prefix) |
| return n; |
| } |
| |
| return first_router; |
| } |
| |
| /* |
| * NET: add new neighbor to list |
| * @param struct neighbor nghb - new neighbor |
| * @return true or false |
| */ |
| int8_t |
| neighbor_add (struct neighbor *nghb) |
| { |
| if (nghb == NULL) |
| return -1; |
| |
| if (first_neighbor == NULL) { |
| first_neighbor = nghb; |
| last_neighbor = first_neighbor; |
| last_neighbor->next = NULL; |
| } else { |
| last_neighbor->next = nghb; |
| last_neighbor = nghb; |
| last_neighbor->next = NULL; |
| } |
| |
| return 1; /* no error */ |
| } |
| |
| /* |
| * NET: create a new neighbor |
| * @param uint8_t *packet - received packet (Ethernet/IPv6/ICMPv6/ND_NghSlct) |
| * @param struct packeth - pointers to headers in packet |
| * @return pointer - pointer to new neighbor |
| * NULL - malloc failed |
| */ |
| void * |
| neighbor_create (uint8_t *packet, struct packeth *headers) |
| { |
| struct neighbor *new_neighbor; |
| |
| new_neighbor = malloc (sizeof(struct neighbor)); |
| if( !new_neighbor ) |
| return NULL; |
| memset(new_neighbor, 0, sizeof(struct neighbor)); |
| |
| /* fill neighbor struct */ |
| memcpy (&(new_neighbor->mac), |
| &(headers->ethh->src_mac[0]), 6); |
| memcpy (&(new_neighbor->ip.addr), &(headers->ip6h->src), IPV6_ADDR_LENGTH); |
| new_neighbor->status = NB_INCOMPLETE; |
| |
| return new_neighbor; |
| } |
| |
| /** |
| * NET: Find neighbor with given IPv6 address in Neighbor Cache |
| * |
| * @param ip - Pointer to IPv6 address |
| * @return pointer - pointer to client IPv6 address (e.g. ::1) |
| * NULL - Neighbor not found |
| */ |
| struct neighbor * |
| find_neighbor(ip6_addr_t ip) |
| { |
| struct neighbor *n = NULL; |
| |
| for (n = first_neighbor; n != NULL ; n=n->next) { |
| if (ip6_cmp(n->ip, ip)) { |
| return n; /* neighbor is already in cache */ |
| } |
| } |
| |
| return NULL; /* neighbor is unknown */ |
| } |
| |
| void ndp_init(void) |
| { |
| /* Router list */ |
| first_router = NULL; |
| last_router = first_router; |
| |
| /* Init Neighbour cache */ |
| first_neighbor = NULL; |
| last_neighbor = first_neighbor; |
| } |