mirror of
https://codeberg.org/1414codeforge/ubgpsuite.git
synced 2025-06-05 21:29:11 +02:00
[*] Initial commit
This commit is contained in:
222
lonetix/include/df/bgp/prefix.h
Executable file
222
lonetix/include/df/bgp/prefix.h
Executable file
@ -0,0 +1,222 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
/**
|
||||
* \file bgp/prefix.h
|
||||
*
|
||||
* Network prefixes types and utilities.
|
||||
*
|
||||
* \copyright The DoubleFourteen Code Forge (C) All Rights Reserved
|
||||
* \author Lorenzo Cogotti
|
||||
*/
|
||||
|
||||
#ifndef DF_BGP_PREFIX_H_
|
||||
#define DF_BGP_PREFIX_H_
|
||||
|
||||
#include "sys/ip.h"
|
||||
|
||||
/**
|
||||
* \brief `Afi` values.
|
||||
*
|
||||
* \see [Address family numbers](https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml)
|
||||
*
|
||||
* \note Address family numbers are in network order (big endian).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define AFI_IP BE16(1)
|
||||
#define AFI_IP6 BE16(2)
|
||||
|
||||
/**
|
||||
* \brief Address Family Identifier, as defined by the BGP protocol.
|
||||
*
|
||||
* \note Address family numbers are in network order (big endian).
|
||||
*/
|
||||
typedef Uint16 Afi;
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \brief `Safi` values.
|
||||
*
|
||||
* \see [SAFI namespace](https://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml)
|
||||
* \see [RFC 4760](http://www.iana.org/go/rfc4760)
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SAFI_UNICAST U8_C(1)
|
||||
#define SAFI_MULTICAST U8_C(2)
|
||||
|
||||
/// Subsequent Address Family Identifier, as defined by the BGP protocol.
|
||||
typedef Uint8 Safi;
|
||||
|
||||
/** @} */
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/**
|
||||
* \brief BGP prefix with PATH ID information
|
||||
*
|
||||
* \warning **Misaligned struct**.
|
||||
* \note Fields are in network order (big endian).
|
||||
*/
|
||||
typedef ALIGNED(1, struct) {
|
||||
Uint32 pathId; ///< Path identifier
|
||||
Uint8 width; ///< Prefix length in bits
|
||||
|
||||
/**
|
||||
* \brief Prefix content `union`.
|
||||
*
|
||||
* \warning Only `PFXLEN(width)` bytes are relevant.
|
||||
*/
|
||||
union {
|
||||
Uint8 bytes[16]; ///< Prefix raw bytes
|
||||
Uint16 words[8]; ///< Prefix contents as a sequence of 16-bits values
|
||||
Uint32 dwords[4]; ///< Prefix contents as a sequence of 32-bits values
|
||||
Ipv4adr v4; ///< Prefix as a **full** IPv4 address
|
||||
Ipv6adr v6; ///< Prefix as a **full** IPv6 address
|
||||
};
|
||||
} ApRawPrefix;
|
||||
|
||||
/**
|
||||
* \brief BGP prefix with no PATH ID information.
|
||||
*
|
||||
* \warning **Misaligned struct**.
|
||||
* \note Fields are in network order (big endian).
|
||||
*/
|
||||
typedef ALIGNED(1, struct) {
|
||||
Uint8 width; ///< Prefix length in bits
|
||||
|
||||
/**
|
||||
* \brief Prefix content `union`.
|
||||
*
|
||||
* \warning Only `PFXLEN(width)` bytes are relevant.
|
||||
*/
|
||||
union {
|
||||
Uint8 bytes[16]; ///< Prefix raw bytes
|
||||
Uint16 words[8]; ///< Prefix contents as a sequence of 16-bits values
|
||||
Uint32 dwords[4]; ///< Prefix contents as a sequence of 32-bits values
|
||||
Ipv4adr v4; ///< Prefix as a **full** IPv4 address
|
||||
Ipv6adr v6; ///< Prefix as a **full** IPv6 address
|
||||
};
|
||||
} RawPrefix;
|
||||
|
||||
/**
|
||||
* \brief "Fat" prefix structure, contains both the actual data and metadata about the BGP prefix itself.
|
||||
*
|
||||
* The structure doesn't reflect the actual BGP protocol format,
|
||||
* it is used whenever a raw BGP data pointer isn't sufficient
|
||||
* to convey enough context for a prefix (e.g. iterating every prefix available
|
||||
* inside a BGP message).
|
||||
*
|
||||
* \warning **Misaligned struct**.
|
||||
* \note Fields are in network order (big endian).
|
||||
*
|
||||
* \note Given the significant amount of metadata, it
|
||||
* should be used sparingly, raw prefixes should be preferred
|
||||
* whenever possible to save the overhead.
|
||||
*/
|
||||
typedef ALIGNED(1, struct) {
|
||||
Boolean8 isAddPath; ///< Whether the path identifier is meaningful or not
|
||||
Afi afi; ///< Prefix address family
|
||||
Safi safi; ///< Prefix subsequent AFI
|
||||
Uint32 pathId; ///< Path identifier (only meaningful if `isAddPath` is `TRUE`)
|
||||
Uint8 width; ///< Prefix width, in bits (maximum legal value depends on AFI)
|
||||
|
||||
/**
|
||||
* \brief Prefix content `union`.
|
||||
*
|
||||
* \warning Only `PFXLEN(width)` bytes are relevant.
|
||||
*/
|
||||
union {
|
||||
Uint8 bytes[16]; ///< Prefix raw bytes
|
||||
Uint16 words[8]; ///< Prefix contents as a sequence of 16-bits values
|
||||
Uint32 dwords[4]; ///< Prefix contents as a sequence of 32-bits values
|
||||
Ipv4adr v4; ///< Prefix as a **full** IPv4 address
|
||||
Ipv6adr v6; ///< Prefix as a **full** IPv6 address
|
||||
};
|
||||
} Prefix;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/// Calculate prefix length in bytes from bit width.
|
||||
#define PFXLEN(width) ((size_t) (((width) >> 3) + (((width) & 7) != 0)))
|
||||
/**
|
||||
* \brief Return pointer to `RawPrefix` portion out of `ApRawPrefix`, `Prefix` or `RawPrefix` itself.
|
||||
*
|
||||
* Cast operation is useful to discard PATH ID information where irrelevant.
|
||||
*/
|
||||
#define PLAINPFX(prefix) ((RawPrefix *) (&(prefix)->width))
|
||||
/// Return pointer to `ApRawPrefix` out of `Prefix` or `ApRawPrefix` itself.
|
||||
#define APPFX(prefix) ((ApRawPrefix *) (&(prefix)->pathId))
|
||||
|
||||
/// Maximum length of an IPv6 prefix encoded as a string.
|
||||
#define PFX6_STRLEN (IPV6_STRLEN + 1 + 3)
|
||||
/// Maximum length of an IPv4 prefix encoded as a string.
|
||||
#define PFX4_STRLEN (IPV4_STRLEN + 1 + 2)
|
||||
/// Maximum length of an IPv6 prefix with PATH ID, encoded as a string.
|
||||
#define APPFX6_STRLEN (10 + 1 + PFX6_STRLEN)
|
||||
/// Maximum length of an IPv4 prefix with PATH ID, encoded as a string.
|
||||
#define APPFX4_STRLEN (10 + 1 + PFX4_STRLEN)
|
||||
/// Maximum length of a prefix encoded as a string.
|
||||
#define PFX_STRLEN PFX6_STRLEN
|
||||
/// Maximum length of a prefix with PATH ID, encoded as a string.
|
||||
#define APPFX_STRLEN APPFX6_STRLEN
|
||||
|
||||
/**
|
||||
* Convert a `RawPrefix` of the specified `Afi` to its string representation.
|
||||
*
|
||||
* \return Pointer to the trailing `\0` inside `dest`.
|
||||
*
|
||||
* \note Assumes `dest` is large enough to hold result (use `[PFX_STRLEN + 1]`)
|
||||
*/
|
||||
char *Bgp_PrefixToString(Afi afi, const RawPrefix *pfx, char *dest);
|
||||
/**
|
||||
* Convert an `ApRawPrefix` of the specified `Afi` to its string representation.
|
||||
*
|
||||
* \return Pointer to the trailing `\0` inside `dest`.
|
||||
*
|
||||
* \note Assumes `dest` is large enough to hold result (use `[APPFX_STRLEN + 1]`)
|
||||
*/
|
||||
char *Bgp_ApPrefixToString(Afi afi, const ApRawPrefix *pfx, char *dest);
|
||||
|
||||
/**
|
||||
* \brief Convert string with format `address/width` to `Prefix`.
|
||||
*
|
||||
* \return `OK` on success, `NG` on invalid prefix string.
|
||||
*
|
||||
* \note Does not handle PATH ID, may only return plain prefixes.
|
||||
*/
|
||||
Judgement Bgp_StringToPrefix(const char *s, Prefix *dest);
|
||||
|
||||
/**
|
||||
* \brief Direct iterator over raw prefix data.
|
||||
*
|
||||
* \note `struct` should be considered opaque.
|
||||
*/
|
||||
typedef struct {
|
||||
Afi afi;
|
||||
Safi safi;
|
||||
Boolean8 isAddPath;
|
||||
|
||||
Uint8 *base, *lim;
|
||||
Uint8 *ptr;
|
||||
} Prefixiter;
|
||||
|
||||
/**
|
||||
* \brief Start iterating `nbytes` bytes from `data` for prefixes of the specified `afi` and `safi`.
|
||||
*
|
||||
* \return `OK` on success, `NG` on error. Sets BGP error, see `Bgp_GetErrStat()`.
|
||||
*/
|
||||
Judgement Bgp_StartPrefixes(Prefixiter *it, Afi afi, Safi safi, const void *data, size_t nbytes, Boolean isAddPath);
|
||||
/**
|
||||
* \brief Get current prefix and advance iterator.
|
||||
*
|
||||
* \return Current prefix on success, depending on `isAddPath` prefix type
|
||||
* may be either `RawPrefix` or `ApRawPrefix`. `NULL` on iteration end or
|
||||
* error. Sets BGP error, see `Bgp_GetErrStat()`.
|
||||
*/
|
||||
void *Bgp_NextPrefix(Prefixiter *it);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user