blob: 1c420d63ee30a5043dbf7090f6448120ad66ae51 [file] [log] [blame]
/******************************************************************************
* 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;
}