186 lines
5 KiB
C
186 lines
5 KiB
C
/******************************************************************************
|
|
* 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
|
|
*****************************************************************************/
|
|
|
|
#ifndef _IPV6_H_
|
|
#define _IPV6_H_
|
|
|
|
#include <stdint.h>
|
|
#include "ethernet.h"
|
|
|
|
#define __IPV6_DEBUG__
|
|
|
|
#ifdef __IPV6_DEBUG__
|
|
#define IPV6_DEBUG_PRINT(format, ...) do { printf(format, ## __VA_ARGS__); } while (0)
|
|
#else
|
|
#define IPV6_DEBUG_PRINT(format, ...)
|
|
#endif
|
|
|
|
#define IPV6_ADDR_LENGTH 16 /* Size of IPv6 adress in bytes */
|
|
#define IPV6_LL_PREFIX 0xFE80000000000000ULL
|
|
#define IPV6_LL_PREFIX_MASK 0xFFC0000000000000ULL
|
|
#define IPV6_SOLIC_NODE_PREFIX 0xFF02000000000000ULL
|
|
#define IPV6_SOLIC_NODE_IFACE_ID 0x00000001FF000000ULL
|
|
|
|
/**
|
|
* An IPv6 Address
|
|
*/
|
|
typedef union {
|
|
uint8_t addr[IPV6_ADDR_LENGTH];
|
|
struct {
|
|
uint64_t prefix;
|
|
uint64_t interface_id;
|
|
} part;
|
|
} ip6_addr_t;
|
|
|
|
typedef struct {
|
|
uint8_t type;
|
|
uint8_t pad[7];
|
|
union {
|
|
ip6_addr_t v6;
|
|
char v4[4];
|
|
} addr;
|
|
} netaddr_t;
|
|
|
|
/** \struct prefix_info
|
|
*
|
|
* List of Prefixes we have adresses from
|
|
* Used for internal purposes, information derived from prefix option
|
|
* in Router Advertisements
|
|
* See RFC 4861 section 4.6.2
|
|
*/
|
|
struct prefix_info {
|
|
uint64_t prefix;
|
|
uint8_t on_link:1, /* When set prefix can be used for on-link
|
|
* determination */
|
|
autoconf:1, /* Prefix can be used for stateless address
|
|
* configuration */
|
|
reserved1:6;
|
|
uint32_t valid_lifetime; /* Time until prefix expires */
|
|
uint32_t preferred_lifetime; /* Time until prefix becomes deprecated */
|
|
uint32_t start_time; /* Time when received */
|
|
uint32_t reserved2;
|
|
struct prefix_info *next;
|
|
};
|
|
|
|
|
|
/* List of IPv6 addresses */
|
|
struct ip6addr_list_entry {
|
|
ip6_addr_t addr;
|
|
struct prefix_info prfx_info;
|
|
struct ip6addr_list_entry *next;
|
|
};
|
|
|
|
/** \struct ip6hdr
|
|
* A header for IPv6 packets.
|
|
* For more information see RFC 2460
|
|
*/
|
|
struct ip6hdr {
|
|
uint32_t ver_tc_fl; /**< Version, Traffic class, Flow label */
|
|
uint16_t pl; /**< Payload length */
|
|
uint8_t nh; /**< Next header */
|
|
uint8_t hl; /**< Hop limit */
|
|
ip6_addr_t src; /**< IPv6 source address */
|
|
ip6_addr_t dst; /**< IPv6 destination address */
|
|
} __attribute((packed));
|
|
|
|
/** \struct packeth
|
|
* Struct with pointers to headers within a packet
|
|
*/
|
|
struct packeth {
|
|
struct ethhdr *ethh;
|
|
struct ip6hdr *ip6h;
|
|
struct icmp6hdr *icmp6h;
|
|
struct udphdr *udph;
|
|
/* ... */
|
|
};
|
|
|
|
/** \struct parseip6_state
|
|
* Stores information about state of IPv6 address parser
|
|
*/
|
|
struct parseip6_state {
|
|
char *lookahead;
|
|
char *ptr;
|
|
const char *addr;
|
|
int state;
|
|
int s1ctr;
|
|
int s2ctr;
|
|
int blocknr;
|
|
int zeroblocks;
|
|
int i;
|
|
int done;
|
|
int errorcode;
|
|
};
|
|
|
|
/** \struct ip6_config
|
|
* Stores flags wheter we use Stateless- or Stateful Autoconfiguration or DHCPv6
|
|
*/
|
|
struct ip6_config {
|
|
uint8_t managed_mode:1,
|
|
other_config:1,
|
|
reserved:6;
|
|
};
|
|
|
|
/******************** VARIABLES **********************************************/
|
|
|
|
extern struct ip6_config ip6_state;
|
|
|
|
/******************** FUNCTIONS *********************************************/
|
|
/* Handles IPv6-packets that are detected by receive_ether. */
|
|
int8_t handle_ipv6(int fd, uint8_t * ip6_packet, uint32_t packetsize);
|
|
|
|
/* Fill IPv6 header */
|
|
void fill_ip6hdr(uint8_t * packet, uint16_t packetsize,
|
|
uint8_t ip_proto, ip6_addr_t *ip6_src, ip6_addr_t *ip6_dst);
|
|
|
|
/* Set own IPv6 address */
|
|
void set_ipv6_address(int fd, ip6_addr_t *own_ip6);
|
|
|
|
/* Get own IPv6 address */
|
|
ip6_addr_t *get_ipv6_address(void);
|
|
|
|
/* Create link-local address from a given Mac Address */
|
|
void ip6_create_ll_address (const uint8_t *own_mac, ip6_addr_t *ll_addr);
|
|
|
|
/* For a given MAC calculates EUI64-Identifier.*/
|
|
uint64_t mac2eui64 (const uint8_t *mac);
|
|
|
|
/* Create empty element for prefix list and return a pointer to it */
|
|
struct prefix_info * ip6_create_prefix_info(void);
|
|
|
|
/* Create a new IPv6 address with a given network prefix
|
|
* and add it to our IPv6 address list */
|
|
void * ip6_prefix2addr (ip6_addr_t prefix);
|
|
|
|
/* Compare IPv6 adresses */
|
|
int8_t ip6_cmp(ip6_addr_t ip_1, ip6_addr_t ip_2);
|
|
|
|
/* Check if it is a link-local address */
|
|
static inline int ip6_is_linklocal(ip6_addr_t *ip)
|
|
{
|
|
return (ip->part.prefix & IPV6_LL_PREFIX_MASK) == IPV6_LL_PREFIX;
|
|
}
|
|
|
|
/* Check if prefix is already in our list */
|
|
int8_t unknown_prefix (ip6_addr_t *ip);
|
|
|
|
/* Send IPv6 packet */
|
|
int send_ipv6 (int fd, void* buffer, int len);
|
|
|
|
/* Add IPv6 address to list */
|
|
int8_t ip6addr_add (struct ip6addr_list_entry *new_address);
|
|
|
|
/* Parse an IPv6 address */
|
|
int parseip6(const char *addr, uint8_t *parsedaddr);
|
|
int str_to_ipv6(const char *str, uint8_t *ip);
|
|
void ipv6_to_str(const uint8_t *ip, char *str);
|
|
|
|
#endif
|