Path: blob/a-new-beginning/SharedDependencies/Sources/libslirp/include/ip6.h
2 views
/* SPDX-License-Identifier: BSD-3-Clause */1/*2* Copyright (c) 20133* Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.4*/56#ifndef SLIRP_IP6_H7#define SLIRP_IP6_H89#include <glib.h>10#include <string.h>1112#include "util.h"1314#define ALLNODES_MULTICAST \15{ \16.s6_addr = { \170xff, \180x02, \190x00, \200x00, \210x00, \220x00, \230x00, \240x00, \250x00, \260x00, \270x00, \280x00, \290x00, \300x00, \310x00, \320x01 \33} \34}3536#define SOLICITED_NODE_PREFIX \37{ \38.s6_addr = { \390xff, \400x02, \410x00, \420x00, \430x00, \440x00, \450x00, \460x00, \470x00, \480x00, \490x00, \500x01, \510xff, \520x00, \530x00, \540x00 \55} \56}5758#define LINKLOCAL_ADDR \59{ \60.s6_addr = { \610xfe, \620x80, \630x00, \640x00, \650x00, \660x00, \670x00, \680x00, \690x00, \700x00, \710x00, \720x00, \730x00, \740x00, \750x00, \760x02 \77} \78}7980#define ZERO_ADDR \81{ \82.s6_addr = { \830x00, \840x00, \850x00, \860x00, \870x00, \880x00, \890x00, \900x00, \910x00, \920x00, \930x00, \940x00, \950x00, \960x00, \970x00, \980x00 \99} \100}101102/* Check that two IPv6 addresses are equal */103static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)104{105return memcmp(a, b, sizeof(*a)) == 0;106}107108/* Check that two IPv6 addresses are equal in their network part */109static inline bool in6_equal_net(const struct in6_addr *a,110const struct in6_addr *b, int prefix_len)111{112if (memcmp(a, b, prefix_len / 8) != 0) {113return 0;114}115116if (prefix_len % 8 == 0) {117return 1;118}119120return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8)) ==121b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));122}123124/* Check that two IPv6 addresses are equal in their machine part */125static inline bool in6_equal_mach(const struct in6_addr *a,126const struct in6_addr *b, int prefix_len)127{128if (memcmp(&(a->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),129&(b->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),13016 - DIV_ROUND_UP(prefix_len, 8)) != 0) {131return 0;132}133134if (prefix_len % 8 == 0) {135return 1;136}137138return (a->s6_addr[prefix_len / 8] &139((1U << (8 - (prefix_len % 8))) - 1)) ==140(b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));141}142143/* Check that the IPv6 is equal to the virtual router */144#define in6_equal_router(a) \145((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \146in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len)) || \147(in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \148in6_equal_mach(a, &slirp->vhost_addr6, 64)))149150/* Check that the IPv6 is equal to the virtual DNS server */151#define in6_equal_dns(a) \152((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len) && \153in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len)) || \154(in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64) && \155in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))156157/* Check that the IPv6 is equal to the host */158#define in6_equal_host(a) (in6_equal_router(a) || in6_equal_dns(a))159160/* Check that the IPv6 is within the sollicited node multicast network */161#define in6_solicitednode_multicast(a) \162(in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))163164/* Check that the IPv6 is zero */165#define in6_zero(a) (in6_equal(a, &(struct in6_addr)ZERO_ADDR))166167/* Compute emulated host MAC address from its ipv6 address */168static inline void in6_compute_ethaddr(struct in6_addr ip,169uint8_t eth[ETH_ALEN])170{171eth[0] = 0x52;172eth[1] = 0x56;173memcpy(ð[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2);174}175176/*177* Definitions for internet protocol version 6.178* Per RFC 2460, December 1998.179*/180#define IP6VERSION 6181#define IP6_HOP_LIMIT 255182183/*184* Structure of an internet header, naked of options.185*/186struct ip6 {187#if (G_BYTE_ORDER == G_BIG_ENDIAN) && !defined(_MSC_VER)188uint8_t ip_v : 4, /* version */189ip_tc_hi : 4; /* traffic class */190uint8_t ip_tc_lo : 4, ip_fl_hi : 4; /* flow label */191#else192uint8_t ip_tc_hi : 4, ip_v : 4;193uint8_t ip_fl_hi : 4, ip_tc_lo : 4;194#endif195uint16_t ip_fl_lo;196uint16_t ip_pl; /* payload length */197uint8_t ip_nh; /* next header */198uint8_t ip_hl; /* hop limit */199struct in6_addr ip_src, ip_dst; /* source and dest address */200};201202/*203* IPv6 pseudo-header used by upper-layer protocols204*/205struct ip6_pseudohdr {206struct in6_addr ih_src; /* source internet address */207struct in6_addr ih_dst; /* destination internet address */208uint32_t ih_pl; /* upper-layer packet length */209uint16_t ih_zero_hi; /* zero */210uint8_t ih_zero_lo; /* zero */211uint8_t ih_nh; /* next header */212};213214/*215* We don't want to mark these ip6 structs as packed as they are naturally216* correctly aligned; instead assert that there is no stray padding.217* If we marked the struct as packed then we would be unable to take218* the address of any of the fields in it.219*/220G_STATIC_ASSERT(sizeof(struct ip6) == 40);221G_STATIC_ASSERT(sizeof(struct ip6_pseudohdr) == 40);222223#endif224225226