diff options
Diffstat (limited to 'roms/SLOF/lib/libnet/ipv6.h')
-rw-r--r-- | roms/SLOF/lib/libnet/ipv6.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/roms/SLOF/lib/libnet/ipv6.h b/roms/SLOF/lib/libnet/ipv6.h new file mode 100644 index 000000000..c6b681d7b --- /dev/null +++ b/roms/SLOF/lib/libnet/ipv6.h @@ -0,0 +1,186 @@ +/****************************************************************************** + * 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 |