blob: 603f502242a8ff68af24572f46a8712a03509740 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INET6_INET6_H_
#define INET6_INET6_H_
#include <endian.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
__BEGIN_CDECLS
typedef struct mac_addr mac_addr_t;
typedef union ip6_addr ip6_addr_t;
typedef struct ip6_hdr ip6_hdr_t;
typedef struct udp_hdr udp_hdr_t;
typedef struct icmp6_hdr icmp6_hdr_t;
typedef struct ndp_n_hdr ndp_n_hdr_t;
#define ETH_ADDR_LEN 6
#define ETH_HDR_LEN 14
#define ETH_MTU 1514
#define IP6_ADDR_LEN 16
#define IP6_U32_LEN 4
#define IP6_U64_LEN 2
#define IP6_HDR_LEN 40
#define IP6_MIN_MTU 1280
#define UDP_HDR_LEN 8
struct mac_addr {
uint8_t x[ETH_ADDR_LEN];
} __attribute__((packed));
union ip6_addr {
uint8_t u8[IP6_ADDR_LEN];
uint32_t u32[IP6_U32_LEN];
uint64_t u64[IP6_U64_LEN];
} __attribute__((packed));
extern const ip6_addr_t ip6_ll_all_nodes;
static inline bool ip6_addr_eq(const ip6_addr_t* a, const ip6_addr_t* b) {
return ((a->u64[0] == b->u64[0]) && (a->u64[1] == b->u64[1]));
}
#define ETH_IP4 0x0800
#define ETH_ARP 0x0806
#define ETH_IP6 0x86DD
#define HDR_HNH_OPT 0
#define HDR_TCP 6
#define HDR_UDP 17
#define HDR_ROUTING 43
#define HDR_FRAGMENT 44
#define HDR_ICMP6 58
#define HDR_NONE 59
#define HDR_DST_OPT 60
struct ip6_hdr {
uint32_t ver_tc_flow;
uint16_t length;
uint8_t next_header;
uint8_t hop_limit;
ip6_addr_t src;
ip6_addr_t dst;
} __attribute__((packed));
struct udp_hdr {
uint16_t src_port;
uint16_t dst_port;
uint16_t length;
uint16_t checksum;
} __attribute__((packed));
#define ICMP6_DEST_UNREACHABLE 1
#define ICMP6_PACKET_TOO_BIG 2
#define ICMP6_TIME_EXCEEDED 3
#define ICMP6_PARAMETER_PROBLEM 4
#define ICMP6_ECHO_REQUEST 128
#define ICMP6_ECHO_REPLY 129
#define ICMP6_NDP_R_ADVERTISE 134
#define ICMP6_NDP_N_SOLICIT 135
#define ICMP6_NDP_N_ADVERTISE 136
struct icmp6_hdr {
uint8_t type;
uint8_t code;
uint16_t checksum;
} __attribute__((packed));
struct ndp_n_hdr {
uint8_t type;
uint8_t code;
uint16_t checksum;
uint32_t flags;
uint8_t target[IP6_ADDR_LEN];
uint8_t options[0];
} __attribute__((packed));
#define NDP_N_SRC_LL_ADDR 1
#define NDP_N_TGT_LL_ADDR 2
#define NDP_N_PREFIX_INFO 3
#define NDP_N_REDIRECTED_HDR 4
#define NDP_N_MTU 5
#ifndef ntohs
#define ntohs(n) be16toh(n)
#define htons(n) htobe16(n)
#endif
#ifndef ntohl
#define ntohl(n) be32toh(n)
#define htonl(n) htobe32(n)
#endif
// Formats an IP6 address into the provided buffer (which must be
// at least IP6TOAMAX bytes in size), and returns the buffer address.
char* ip6toa(char* _out, const void* ip6addr);
#define IP6TOAMAX 40
// provided by inet6.c
void ip6_init(void* macaddr, bool quiet);
void eth_recv(void* data, size_t len);
typedef struct eth_buffer eth_buffer_t;
// provided by interface driver
zx_status_t eth_get_buffer(size_t len, void** data, eth_buffer_t** out, bool block);
void eth_put_buffer(eth_buffer_t* ethbuf);
zx_status_t eth_send(eth_buffer_t* ethbuf, size_t skip, size_t len);
int eth_add_mcast_filter(const mac_addr_t* addr);
// call to transmit a UDP packet
zx_status_t udp6_send(const void* data, size_t len, const ip6_addr_t* daddr, uint16_t dport,
uint16_t sport, bool block);
// implement to recive UDP packets
void udp6_recv(void* data, size_t len, const ip6_addr_t* daddr, uint16_t dport,
const ip6_addr_t* saddr, uint16_t sport);
unsigned ip6_checksum(ip6_hdr_t* ip, unsigned type, size_t length);
void send_router_advertisement(void);
// NOTES
//
// This is an extremely minimal IPv6 stack, supporting just enough
// functionality to talk to link local hosts over UDP.
//
// It responds to ICMPv6 Neighbor Solicitations for its link local
// address, which is computed from the mac address provided by the
// ethernet interface driver.
//
// It responds to PINGs.
//
// It can only transmit to multicast addresses or to the address it
// last received a packet from (general usecase is to reply to a UDP
// packet from the UDP callback, which this supports)
//
// It does not currently do duplicate address detection, which is
// probably the most severe bug.
//
// It does not support any IPv6 options and will drop packets with
// options.
//
// It expects the network stack to provide transmit buffer allocation
// and free functionality. It will allocate a single transmit buffer
// from udp6_send() or icmp6_send() to fill out and either pass to the
// network stack via eth_send() or, in the event of an error, release
// via eth_put_buffer().
//
__END_CDECLS
#endif // INET6_INET6_H_