/****************************************************************************** * 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 #include #include #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[0]), 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; }