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

📄 v3_addr.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 3 页
字号:
    *result = aor;  return 1; err:  IPAddressOrRange_free(aor);  return 0;}/* * Construct a range.  If it can be expressed as a prefix, * return a prefix instead.  Doing this here simplifies * the rest of the code considerably. */static int make_addressRange(IPAddressOrRange **result,			     unsigned char *min,			     unsigned char *max,			     const int length){  IPAddressOrRange *aor;  int i, prefixlen;  if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)    return make_addressPrefix(result, min, prefixlen);  if ((aor = IPAddressOrRange_new()) == NULL)    return 0;  aor->type = IPAddressOrRange_addressRange;  OPENSSL_assert(aor->u.addressRange == NULL);  if ((aor->u.addressRange = IPAddressRange_new()) == NULL)    goto err;  if (aor->u.addressRange->min == NULL &&      (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)    goto err;  if (aor->u.addressRange->max == NULL &&      (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)    goto err;  for (i = length; i > 0 && min[i - 1] == 0x00; --i)    ;  if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))    goto err;  aor->u.addressRange->min->flags &= ~7;  aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;  if (i > 0) {    unsigned char b = min[i - 1];    int j = 1;    while ((b & (0xFFU >> j)) != 0)       ++j;    aor->u.addressRange->min->flags |= 8 - j;  }  for (i = length; i > 0 && max[i - 1] == 0xFF; --i)    ;  if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))    goto err;  aor->u.addressRange->max->flags &= ~7;  aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;  if (i > 0) {    unsigned char b = max[i - 1];    int j = 1;    while ((b & (0xFFU >> j)) != (0xFFU >> j))      ++j;    aor->u.addressRange->max->flags |= 8 - j;  }  *result = aor;  return 1; err:  IPAddressOrRange_free(aor);  return 0;}/* * Construct a new address family or find an existing one. */static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,					     const unsigned afi,					     const unsigned *safi){  IPAddressFamily *f;  unsigned char key[3];  unsigned keylen;  int i;  key[0] = (afi >> 8) & 0xFF;  key[1] = afi & 0xFF;  if (safi != NULL) {    key[2] = *safi & 0xFF;    keylen = 3;  } else {    keylen = 2;  }  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {    f = sk_IPAddressFamily_value(addr, i);    OPENSSL_assert(f->addressFamily->data != NULL);    if (f->addressFamily->length == keylen &&	!memcmp(f->addressFamily->data, key, keylen))      return f;  }  if ((f = IPAddressFamily_new()) == NULL)    goto err;  if (f->ipAddressChoice == NULL &&      (f->ipAddressChoice = IPAddressChoice_new()) == NULL)    goto err;  if (f->addressFamily == NULL &&       (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)    goto err;  if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))    goto err;  if (!sk_IPAddressFamily_push(addr, f))    goto err;  return f; err:  IPAddressFamily_free(f);  return NULL;}/* * Add an inheritance element. */int v3_addr_add_inherit(IPAddrBlocks *addr,			const unsigned afi,			const unsigned *safi){  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);  if (f == NULL ||      f->ipAddressChoice == NULL ||      (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&       f->ipAddressChoice->u.addressesOrRanges != NULL))    return 0;  if (f->ipAddressChoice->type == IPAddressChoice_inherit &&      f->ipAddressChoice->u.inherit != NULL)    return 1;  if (f->ipAddressChoice->u.inherit == NULL &&      (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)    return 0;  f->ipAddressChoice->type = IPAddressChoice_inherit;  return 1;}/* * Construct an IPAddressOrRange sequence, or return an existing one. */static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,					       const unsigned afi,					       const unsigned *safi){  IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);  IPAddressOrRanges *aors = NULL;  if (f == NULL ||      f->ipAddressChoice == NULL ||      (f->ipAddressChoice->type == IPAddressChoice_inherit &&       f->ipAddressChoice->u.inherit != NULL))    return NULL;  if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)    aors = f->ipAddressChoice->u.addressesOrRanges;  if (aors != NULL)    return aors;  if ((aors = sk_IPAddressOrRange_new_null()) == NULL)    return NULL;  switch (afi) {  case IANA_AFI_IPV4:    (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);    break;  case IANA_AFI_IPV6:    (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);    break;  }  f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;  f->ipAddressChoice->u.addressesOrRanges = aors;  return aors;}/* * Add a prefix. */int v3_addr_add_prefix(IPAddrBlocks *addr,		       const unsigned afi,		       const unsigned *safi,		       unsigned char *a,		       const int prefixlen){  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);  IPAddressOrRange *aor;  if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))    return 0;  if (sk_IPAddressOrRange_push(aors, aor))    return 1;  IPAddressOrRange_free(aor);  return 0;}/* * Add a range. */int v3_addr_add_range(IPAddrBlocks *addr,		      const unsigned afi,		      const unsigned *safi,		      unsigned char *min,		      unsigned char *max){  IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);  IPAddressOrRange *aor;  int length = length_from_afi(afi);  if (aors == NULL)    return 0;  if (!make_addressRange(&aor, min, max, length))    return 0;  if (sk_IPAddressOrRange_push(aors, aor))    return 1;  IPAddressOrRange_free(aor);  return 0;}/* * Extract min and max values from an IPAddressOrRange. */static void extract_min_max(IPAddressOrRange *aor,			    unsigned char *min,			    unsigned char *max,			    int length){  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);  switch (aor->type) {  case IPAddressOrRange_addressPrefix:    addr_expand(min, aor->u.addressPrefix, length, 0x00);    addr_expand(max, aor->u.addressPrefix, length, 0xFF);    return;  case IPAddressOrRange_addressRange:    addr_expand(min, aor->u.addressRange->min, length, 0x00);    addr_expand(max, aor->u.addressRange->max, length, 0xFF);    return;  }}/* * Public wrapper for extract_min_max(). */int v3_addr_get_range(IPAddressOrRange *aor,		      const unsigned afi,		      unsigned char *min,		      unsigned char *max,		      const int length){  int afi_length = length_from_afi(afi);  if (aor == NULL || min == NULL || max == NULL ||      afi_length == 0 || length < afi_length ||      (aor->type != IPAddressOrRange_addressPrefix &&       aor->type != IPAddressOrRange_addressRange))    return 0;  extract_min_max(aor, min, max, afi_length);  return afi_length;}/* * Sort comparision function for a sequence of IPAddressFamily. * * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about * the ordering: I can read it as meaning that IPv6 without a SAFI * comes before IPv4 with a SAFI, which seems pretty weird.  The * examples in appendix B suggest that the author intended the * null-SAFI rule to apply only within a single AFI, which is what I * would have expected and is what the following code implements. */static int IPAddressFamily_cmp(const IPAddressFamily * const *a_,			       const IPAddressFamily * const *b_){  const ASN1_OCTET_STRING *a = (*a_)->addressFamily;  const ASN1_OCTET_STRING *b = (*b_)->addressFamily;  int len = ((a->length <= b->length) ? a->length : b->length);  int cmp = memcmp(a->data, b->data, len);  return cmp ? cmp : a->length - b->length;}/* * Check whether an IPAddrBLocks is in canonical form. */int v3_addr_is_canonical(IPAddrBlocks *addr){  unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];  unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];  IPAddressOrRanges *aors;  int i, j, k;  /*   * Empty extension is cannonical.   */  if (addr == NULL)    return 1;  /*   * Check whether the top-level list is in order.   */  for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {    const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);    const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);    if (IPAddressFamily_cmp(&a, &b) >= 0)      return 0;  }  /*   * Top level's ok, now check each address family.   */  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);    int length = length_from_afi(v3_addr_get_afi(f));    /*     * Inheritance is canonical.  Anything other than inheritance or     * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.     */    if (f == NULL || f->ipAddressChoice == NULL)      return 0;    switch (f->ipAddressChoice->type) {    case IPAddressChoice_inherit:      continue;    case IPAddressChoice_addressesOrRanges:      break;    default:      return 0;    }    /*     * It's an IPAddressOrRanges sequence, check it.     */    aors = f->ipAddressChoice->u.addressesOrRanges;    if (sk_IPAddressOrRange_num(aors) == 0)      return 0;    for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);      IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);      extract_min_max(a, a_min, a_max, length);      extract_min_max(b, b_min, b_max, length);      /*       * Punt misordered list, overlapping start, or inverted range.       */      if (memcmp(a_min, b_min, length) >= 0 ||	  memcmp(a_min, a_max, length) > 0 ||	  memcmp(b_min, b_max, length) > 0)	return 0;      /*       * Punt if adjacent or overlapping.  Check for adjacency by       * subtracting one from b_min first.       */      for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)	;      if (memcmp(a_max, b_min, length) >= 0)	return 0;      /*       * Check for range that should be expressed as a prefix.       */      if (a->type == IPAddressOrRange_addressRange &&	  range_should_be_prefix(a_min, a_max, length) >= 0)	return 0;    }    /*     * Check final range to see if it should be a prefix.     */    j = sk_IPAddressOrRange_num(aors) - 1;    {      IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);      if (a->type == IPAddressOrRange_addressRange) {	extract_min_max(a, a_min, a_max, length);	if (range_should_be_prefix(a_min, a_max, length) >= 0)	  return 0;      }    }  }  /*   * If we made it through all that, we're happy.   */  return 1;}/* * Whack an IPAddressOrRanges into canonical form. */static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,				      const unsigned afi){  int i, j, length = length_from_afi(afi);  /*   * Sort the IPAddressOrRanges sequence.   */  sk_IPAddressOrRange_sort(aors);  /*   * Clean up representation issues, punt on duplicates or overlaps.   */  for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {    IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);    IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];    extract_min_max(a, a_min, a_max, length);    extract_min_max(b, b_min, b_max, length);    /*     * Punt overlaps.     */    if (memcmp(a_max, b_min, length) >= 0)      return 0;    /*     * Merge if a and b are adjacent.  We check for     * adjacency by subtracting one from b_min first.     */    for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)      ;    if (memcmp(a_max, b_min, length) == 0) {      IPAddressOrRange *merged;      if (!make_addressRange(&merged, a_min, b_max, length))	return 0;      sk_IPAddressOrRange_set(aors, i, merged);

⌨️ 快捷键说明

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