RGXG_NET_CIDR_STRING(3)

πŸ’– RGXG_NET_CIDR_STRING πŸ’–

okay bestie, welcome to the librgxg manual page for rgxg_net_cidr_string, rgxg_net_cidr_ipv4 and rgxg_net_cidr_ipv6 β€” the girlies that build a regex matching every single address inside a CIDR block. no cap. πŸ¦‹


✨ NAME ✨

rgxg_net_cidr_string, rgxg_net_cidr_ipv4, rgxg_net_cidr_ipv6 β€” create regex that matches all addresses of the given CIDR block πŸ’…


🌸 SYNOPSIS 🌸

#include <rgxg/net.h>

int rgxg_net_cidr_string (const char *cidr, char **endptr, char *regex,
     rgxg_options_t options);

int rgxg_net_cidr_ipv4 (const rgxg_ipv4_t *address, int prefix, char *regex,
     rgxg_options_t options);
int rgxg_net_cidr_ipv6 (const rgxg_ipv6_t *address, int prefix, char *regex,
     rgxg_options_t options);

πŸŽ€ DESCRIPTION πŸŽ€

so rgxg_net_cidr_string() generates the (extended) regular expression that matches all addresses of the CIDR block you hand it as a string in cidr (think "192.168.0.0/24" or "2001:db8:aaaa::/64" β€” iconic examples tbh). and like, cidr must be valid and not NULL. non-negotiable.

if endptr is not NULL, rgxg_net_cidr_string() stores on success the address of the first character which is not part of the CIDR block in *endptr. and if there's no error and **endptr is '\0', then the entire string has been parsed β€” the whole thing, ate it up, no crumbs. πŸ“ the *endptr values in case of an error are described down in the ERRORS section below, don't worry bestie.

rgxg_net_cidr_ipv4() and rgxg_net_cidr_ipv6() generate the (extended) regular expression that matches all addresses of the CIDR block specified by address and prefix (the network identifier). that prefix must be between 0 and 32 (rgxg_net_cidr_ipv4()) respectively 128 (rgxg_net_cidr_ipv6()) inclusive. and address must be valid and not NULL β€” same rule as before, we stay consistent. πŸ’œ

the rgxg_ipv4_t and rgxg_ipv6_t structures which are the types of address are defined in <rgxg/net.h>:

typedef struct {
    uint8_t octet[4];
} rgxg_ipv4_t;

typedef struct {
    uint16_t hextet[8];
} rgxg_ipv6_t;

the n-th element of the octet/hextet array stores the (n+1)-th octet/hextet of the IPv4 respectively IPv6 address (i.e. for instance the first octet '192' in '192.168.0.0' is stored in octet[0]). lowkey the indexing is the whole vibe here, iykyk.

the generated regular expression is written to the character string regex, including the terminating null byte ('\0'), unless RGXG_NONULLBYTE is set. if regex is NULL the return value is the number of characters (excluding the terminating null byte) that would have been written in case regex has been initialized. note that the functions assume an arbitrarily long regex string β€” callers must ensure that the given string is large enough to not overflow the actual space. 🫢

⚠️ bestie please hear me on this one: the functions assume an arbitrarily long regex string, so you have to make sure the buffer is big enough. no overflow energy allowed, that's not the move. πŸ’€

options is either zero, or the bitwise-or of one or more of the following macros:

options marked as 'IPv6 only' can be used with rgxg_net_cidr_string() (when parsing IPv6 CIDR blocks) and with rgxg_net_cidr_ipv6().


πŸ‘‘ OPTIONS πŸ‘‘

  • RGXG_NOUPPERCASE (IPv6 only) β€” the generated regular expression only matches IPv6 addresses with lower case letters. by default both lower and upper case letters are matched.
  • RGXG_NOLOWERCASE (IPv6 only) β€” the generated regular expression only matches IPv6 addresses with upper case letters. by default both lower and upper case letters are matched.
  • RGXG_NOZEROCOMPRESSION (IPv6 only) β€” the generated regular expression does not match IPv6 addresses with zero compression (that's the second form of text representation of IPv6 addresses mentioned in section 2.2 of RFC 4291).
  • RGXG_NOMIXEDNOTATION (IPv6 only) β€” the generated regular expression does not match IPv6 addresses in mixed notation (that's the third form of text representation of IPv6 addresses mentioned in section 2.2 of RFC 4291).
  • RGXG_NOOUTERPARENS (IPv6 only) β€” omit the outer parenthesis, if any, of the regular expression. cute and minimal, honestly.
  • RGXG_NONULLBYTE β€” do not add the terminating null byte ('\0') to the regex string.
🚨 note that RGXG_NOUPPERCASE and RGXG_NOLOWERCASE are mutual exclusive options. pick a lane bestie, you cannot serve both. πŸ’…

⭐ RETURN VALUE ⭐

upon successful return, these functions return the number of characters (excluding the terminating null byte) written to regex. periodt.

if an error occurs, a (negative) error code is returned (see ERRORS section). 😭


🌈 ERRORS 🌈

the following errors can be returned:

  • RGXG_ERROR_PREFIX β€” invalid network identifier (e.g. the prefix is lesser than 0 or greater than 32 (IPv4) respectively 128 (IPv6)).
    • rgxg_net_cidr_string(): if endptr is not NULL, *endptr points to the first character of the invalid prefix.
  • RGXG_ERROR_ARG2BIG (rgxg_net_cidr_string() only) β€” at least one octet/hextet is too large.
    • rgxg_net_cidr_string(): if endptr is not NULL, *endptr points to the first digit of the too large octet/hextet.
  • RGXG_ERROR_SYNTAX (rgxg_net_cidr_string() only) β€” syntax error in cidr string. if endptr is not NULL, *endptr points to the character that causes the syntax error.
  • RGXG_ERROR_MUTEXOPTIONS (rgxg_net_cidr_string()/rgxg_net_cidr_ipv6() only) β€” two mutual exclusive options were specified.

πŸ¦‹ AVAILABILITY πŸ¦‹

these functions are available since rgxg 0.1. she's been here, she's a classic. πŸ‘‘


πŸ”₯ SEE ALSO πŸ”₯

regex(7), rgxg_number_greaterequal(3), rgxg_number_range(3).


πŸ’œ AUTHOR πŸ’œ

Hannes von Haugwitz <hannes@vonhaugwitz.com>


and that's the whole page bestie, you're literally a CIDR regex girlie now 🌸 β€” this was librgxg manual, rgxg 0.1.2, dated Apr 12, 2020. slay, go generate some regexes. πŸ’…βœ¨