⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bnf.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 2 页
字号:
 * @retval Length of valid IP6 address or -1 upon an error. * * @note Scanned IP6 is not always NUL-terminated. */int scan_ip6_address(char **inout_host){  int n, canonize = 0;  char *host = *inout_host;  char *hexparts[9] = { NULL };  n = span_canonic_ip6_address(host, &canonize, hexparts);  if (n == 0)    return -1;  *inout_host += n;  if (canonize) {    int len = canonize_ip6_address(host, hexparts);    assert(len <= n);    if (len < n)      host[len] = '\0';  }  return n;}/** Return length of valid IP6 reference. */int span_ip6_reference(char const *host){  /* IPv6reference  =  "[" IPv6address "]" */  if (host && host[0] == '[') {    int n = span_ip6_address(host + 1);    if (n > 0 && host[n + 1] == ']')      return n + 2;  }  return 0;}/** Scan valid IP6 reference. */int scan_ip6_reference(char **inout_host){  int n, canonize = 0;  char *host = *inout_host;  char *hexparts[9] = { NULL };  /* IPv6reference  =  "[" IPv6address "]" */  if (host == NULL ||      host[0] != '[' ||      (n = span_canonic_ip6_address(host + 1, &canonize, hexparts)) == 0 ||      host[n + 1] != ']')    return -1;  *inout_host += n + 2;  if (canonize) {    int len = canonize_ip6_address(host + 1, hexparts);    assert(len <= n);    host[len + 1] = ']';    if (len + 2 < n + 2)      host[len + 2] = '\0';  }  return n + 2;}/** Return length of valid IP4 or IP6 address. */int span_ip_address(char const *host){  if (!host || !host[0])    return 0;  /* IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet */  if (IS_DIGIT(host[0])) {    int n = span_ip4_address(host);    if (n)      return n;  }  if (host[0] == '[')    return span_ip6_reference(host);  else    return span_ip6_address(host);}/** Scan valid IP4/IP6 address. */int scan_ip_address(char **inout_host){  char *host = *inout_host;  if (host == NULL)    return -1;  /* IPv6reference  =  "[" IPv6address "]" */  if (host[0] == '[')    return scan_ip6_reference(inout_host);  if (IS_DIGIT(host[0])) {    int n = scan_ip4_address(inout_host);    if (n > 0)      return n;  }  return scan_ip6_address(inout_host);}/** Return length of a valid domain label */su_inlinesize_t span_domain_label(char const *label){  /* domainlabel =  alphanum / alphanum *( alphanum / "-" ) alphanum */  if (IS_ALPHANUM(*label)) {    size_t n;    for (n = 1; IS_ALPHANUM(label[n]) || label[n] == '-'; n++)      ;    if (IS_ALPHANUM(label[n - 1]))      return n;  }  return 0;}/** Scan valid domain name and count number of labels in it. */su_inlinesize_t span_domain_labels(char const *host, size_t *return_labels){  size_t len, n, labels;  int c;  if (!host || !host[0])    return 0;  for (n = 0, labels = 0; ; n += len) {    len = span_domain_label(host + n);    if (len == 0)      return 0;    labels++;    if (host[n + len] != '.')      break;    len++;    if (!IS_ALPHANUM(host[n + len]))      break;  }  /* Check that last label does not start with number */  if (!IS_ALPHA(host[n]))    return 0;  c = host[n + len];  if (IS_ALPHANUM(c) || c == '-' || c == '.')    return 0;  if (return_labels)    *return_labels = labels;  return n + len;}/** Return length of a valid domain name. * * @code * hostname         =  *( domainlabel "." ) toplabel [ "." ] * domainlabel      =  alphanum *                     / alphanum *( alphanum / "-" ) alphanum * toplabel         =  ALPHA / ALPHA *( alphanum / "-" ) alphanum * @endcode */isize_t span_domain(char const *host){  return span_domain_labels(host, NULL);}/** Scan valid domain name. */issize_t scan_domain(char **inout_host){  char *host;  size_t n, labels;  n = span_domain_labels(host = *inout_host, &labels);  if (n == 0)    return -1;  /* Remove extra dot at the end of hostname */  if (labels > 1 && host[n - 1] == '.')    host[n - 1] = '\0';  *inout_host += n;  return n;}/** Return length of a valid domain name or IP address. */isize_t span_host(char const *host){ if (!host || !host[0])    return 0;  if (host[0] == '[')    return span_ip6_reference(host);  if (IS_DIGIT(host[0])) {    int n = span_ip4_address(host);    if (n)      return (isize_t)n;  }  return span_domain(host);}/** Scan valid domain name or IP address. */issize_t scan_host(char **inout_host){  char *host = *inout_host;  if (host == NULL)    return -1;  /* IPv6reference  =  "[" IPv6address "]" */  if (host[0] == '[')    return scan_ip6_reference(inout_host);  if (IS_DIGIT(host[0])) {    int n = scan_ip4_address(inout_host);    if (n > 0)      return (issize_t)n;  }  return scan_domain(inout_host);}#include <sofia-sip/hostdomain.h>/** Return true if @a string is valid IP4 address in dot-notation. * * @note Only 4-octet form is accepted, e.g., @c 127.1 is not considered * valid IP4 address. */int host_is_ip4_address(char const *string){  int n = span_ip4_address(string);  return n > 0 && string[n] == '\0';}/** Return true if @a string is valid IP6 address in hex notation. * * E.g., fe80::1 is a valid IP6 address.  */int host_is_ip6_address(char const *string){  int n = span_ip6_address(string);  return n > 0 && string[n] == '\0';}int host_ip6_reference(char const *string){  return host_is_ip6_reference(string);}/** Return true if @a string is valid IP6 reference,  *  i.e. hex notation in square brackets. * * E.g., [::1] is a valid IP6 reference. */int host_is_ip6_reference(char const *string){  int n = span_ip6_reference(string);  return n > 0 && string[n] == '\0';}/** Return true if @a string is valid IP address. * * Valid IP address is either a IP4 adddress in quad-octet notation,  * IP6 hex address or IP6 reference in square brackets ([]). */int host_is_ip_address(char const *string){  int n = span_ip_address(string);  return n > 0 && string[n] == '\0';}/** Return true if @a string is valid a domain name. * * Valid domain name consists of alphanumeric labels separated with  * dot ("."). There can be a "-" in the middle of label. * The last label must start with a letter. * * @code * hostname         =  *( domainlabel "." ) toplabel [ "." ] * domainlabel      =  alphanum *                     / alphanum *( alphanum / "-" ) alphanum * toplabel         =  ALPHA / ALPHA *( alphanum / "-" ) alphanum * @endcode */int host_is_domain(char const *string){  size_t n = string ? span_domain(string) : 0;  return string && n > 0 && string[n] == '\0';}/** Return true if @a string is valid a host name. * * Check if the @a string is a domain name, IP address or IP6 reference. */int host_is_valid(char const *string){  size_t n = span_host(string);  return n > 0 && string[n] == '\0';}/** Returns true if @a string is describing a local address. * * Uses the definitions of local addresses found in RFC1700 and  * RFC4291.  */int host_is_local(char const *host){  size_t n;  if (host_is_ip6_reference(host))    return (strcmp(host, "[::1]") == 0);  else if (host_is_ip6_address(host))    return (strcmp(host, "::1") == 0);  else if (host_is_ip4_address(host))    return (strncmp(host, "127.", 4) == 0);  n = span_domain(host);  return     n >= 9 /* strlen("localhost") */ &&    strncasecmp(host, "localhost", 9) == 0 &&    (n == 9 ||      ((n == 10 || /* localhost. */       n == 21 || /* strlen("localhost.localdomain") */       n == 22) && /* strlen("localhost.localdomain.") */      strncasecmp(host + 9, ".localdomain.", n - 9) == 0));}/** Return true if @a string has domain name in "invalid." domain. * */int host_has_domain_invalid(char const *string){  size_t n = span_domain(string);  if (n >= 7 && string[n] == '\0') {    static char const invalid[] = ".invalid";    if (string[n - 1] == '.')	/* .invalid. perhaps? */      n--;    if (n == 7 /* strlen("invalid") */)      return strncasecmp(string, invalid + 1, 7) == 0;    else      return strncasecmp(string + n - 8, invalid, 8) == 0;  }  return 0;}#include <sofia-sip/su.h>static size_t convert_ip_address(char const *s,				 uint8_t addr[16],				 size_t *return_addrlen){  size_t len;  int canonize = 0;  char buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];#if SU_HAVE_IN6  len = span_ip6_reference(s);  if (len) {    assert(len - 2 < sizeof buf); assert(len > 2);    if (s[len])      return 0;    len = len - 2;    s = memcpy(buf, s + 1, len), buf[len] = '\0';  }  else    len = span_ip6_address(s);  if (len) {    if (s[len] == '\0' && su_inet_pton(AF_INET6, s, addr) == 1) {      if (SU_IN6_IS_ADDR_V4MAPPED(addr) ||	  SU_IN6_IS_ADDR_V4COMPAT(addr)) {	memcpy(addr, addr + 12, 4);	return (void)(*return_addrlen = 4), len;      }      return (void)(*return_addrlen = 16), len;    }  }  else#endif  len = span_canonic_ip4_address(s, &canonize);  if (len) {    if (canonize) {      char *tmp = buf;      s = memcpy(tmp, s, len + 1);      scan_ip4_address(&tmp);          }    if (s[len] == '\0' && su_inet_pton(AF_INET, s, addr) == 1)      return (void)(*return_addrlen = 4), len;  }  return 0;}/** Compare two host names or IP addresses * * Converts valid IP addresses to the binary format before comparing them.  * Note that IP6-mapped IP4 addresses and IP6-compatible IP4 addresses are * compared as IP4 addresses; that is, ::ffff:127.0.0.1, ::127.0.0.1 and * 127.0.0.1 all are all equal. * * @param a IP address or domain name * @param b IP address or domain name *  * @retval -1 if a < b * @retval 0 if a == b * @retval 1 if a > b * * @since New in @VERSION_1_12_4. */int host_cmp(char const *a, char const *b){  uint8_t a6[16], b6[16];  size_t alen, blen, asize = 0, bsize = 0;  int retval;  if (a == NULL || b == NULL) {    retval = (a != NULL) - (b != NULL);  }  else {    alen = convert_ip_address(a, a6, &asize);    blen = convert_ip_address(b, b6, &bsize);    if (alen > 0 && blen > 0) {      if (asize < bsize)	retval = -1;      else if (asize > bsize)	retval = 1;      else	retval = memcmp(a6, b6, asize);    }    else {      retval = strcasecmp(a, b);    }  }  return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -