📄 addr_families.c
字号:
* * @param context a Keberos context * @param af address family * @param sa sockaddr * @param sa_size lenght of sa. * @param port for to fill into sa. * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_anyaddr (krb5_context context, int af, struct sockaddr *sa, krb5_socklen_t *sa_size, int port){ struct addr_operations *a = find_af (af); if (a == NULL) { krb5_set_error_string (context, "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } (*a->anyaddr)(sa, sa_size, port); return 0;}/** * krb5_print_address prints the address in addr to the string string * that have the length len. If ret_len is not NULL, it will be filled * with the length of the string if size were unlimited (not including * the final NUL) . * * @param addr address to be printed * @param str pointer string to print the address into * @param len length that will fit into area pointed to by "str". * @param ret_len return length the str. * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_print_address (const krb5_address *addr, char *str, size_t len, size_t *ret_len){ struct addr_operations *a = find_atype(addr->addr_type); int ret; if (a == NULL || a->print_addr == NULL) { char *s; int l; int i; s = str; l = snprintf(s, len, "TYPE_%d:", addr->addr_type); if (l < 0 || l >= len) return EINVAL; s += l; len -= l; for(i = 0; i < addr->address.length; i++) { l = snprintf(s, len, "%02x", ((char*)addr->address.data)[i]); if (l < 0 || l >= len) return EINVAL; len -= l; s += l; } if(ret_len != NULL) *ret_len = s - str; return 0; } ret = (*a->print_addr)(addr, str, len); if (ret < 0) return EINVAL; if(ret_len != NULL) *ret_len = ret; return 0;}/** * krb5_parse_address returns the resolved hostname in string to the * krb5_addresses addresses . * * @param context a Keberos context * @param string * @param addresses * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_parse_address(krb5_context context, const char *string, krb5_addresses *addresses){ int i, n; struct addrinfo *ai, *a; int error; int save_errno; addresses->len = 0; addresses->val = NULL; for(i = 0; i < num_addrs; i++) { if(at[i].parse_addr) { krb5_address addr; if((*at[i].parse_addr)(context, string, &addr) == 0) { ALLOC_SEQ(addresses, 1); if (addresses->val == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } addresses->val[0] = addr; return 0; } } } error = getaddrinfo (string, NULL, NULL, &ai); if (error) { save_errno = errno; krb5_set_error_string (context, "%s: %s", string, gai_strerror(error)); return krb5_eai_to_heim_errno(error, save_errno); } n = 0; for (a = ai; a != NULL; a = a->ai_next) ++n; ALLOC_SEQ(addresses, n); if (addresses->val == NULL) { krb5_set_error_string(context, "malloc: out of memory"); freeaddrinfo(ai); return ENOMEM; } addresses->len = 0; for (a = ai, i = 0; a != NULL; a = a->ai_next) { if (krb5_sockaddr2address (context, ai->ai_addr, &addresses->val[i])) continue; if(krb5_address_search(context, &addresses->val[i], addresses)) continue; addresses->len = i; i++; } freeaddrinfo (ai); return 0;}/** * krb5_address_order compares the addresses addr1 and addr2 so that * it can be used for sorting addresses. If the addresses are the same * address krb5_address_order will return 0. Behavies like memcmp(2). * * @param context a Keberos context * @param addr1 krb5_address to compare * @param addr2 krb5_address to compare * * @return < 0 if address addr1 in "less" then addr2. 0 if addr1 and * addr2 is the same address, > 0 if addr2 is "less" then addr1. * * @ingroup krb5_address */int KRB5_LIB_FUNCTIONkrb5_address_order(krb5_context context, const krb5_address *addr1, const krb5_address *addr2){ /* this sucks; what if both addresses have order functions, which should we call? this works for now, though */ struct addr_operations *a; a = find_atype(addr1->addr_type); if(a == NULL) { krb5_set_error_string (context, "Address family %d not supported", addr1->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } if(a->order_addr != NULL) return (*a->order_addr)(context, addr1, addr2); a = find_atype(addr2->addr_type); if(a == NULL) { krb5_set_error_string (context, "Address family %d not supported", addr2->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } if(a->order_addr != NULL) return (*a->order_addr)(context, addr1, addr2); if(addr1->addr_type != addr2->addr_type) return addr1->addr_type - addr2->addr_type; if(addr1->address.length != addr2->address.length) return addr1->address.length - addr2->address.length; return memcmp (addr1->address.data, addr2->address.data, addr1->address.length);}/** * krb5_address_compare compares the addresses addr1 and addr2. * Returns TRUE if the two addresses are the same. * * @param context a Keberos context * @param addr1 address to compare * @param addr2 address to compare * * @return Return an TRUE is the address are the same FALSE if not * * @ingroup krb5_address */krb5_boolean KRB5_LIB_FUNCTIONkrb5_address_compare(krb5_context context, const krb5_address *addr1, const krb5_address *addr2){ return krb5_address_order (context, addr1, addr2) == 0;}/** * krb5_address_search checks if the address addr is a member of the * address set list addrlist . * * @param context a Keberos context. * @param addr address to search for. * @param addrlist list of addresses to look in for addr. * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_boolean KRB5_LIB_FUNCTIONkrb5_address_search(krb5_context context, const krb5_address *addr, const krb5_addresses *addrlist){ int i; for (i = 0; i < addrlist->len; ++i) if (krb5_address_compare (context, addr, &addrlist->val[i])) return TRUE; return FALSE;}/** * krb5_free_address frees the data stored in the address that is * alloced with any of the krb5_address functions. * * @param context a Keberos context * @param address addresss to be freed. * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_free_address(krb5_context context, krb5_address *address){ struct addr_operations *a = find_atype (address->addr_type); if(a != NULL && a->free_addr != NULL) return (*a->free_addr)(context, address); krb5_data_free (&address->address); memset(address, 0, sizeof(*address)); return 0;}/** * krb5_free_addresses frees the data stored in the address that is * alloced with any of the krb5_address functions. * * @param context a Keberos context * @param addresses addressses to be freed. * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_free_addresses(krb5_context context, krb5_addresses *addresses){ int i; for(i = 0; i < addresses->len; i++) krb5_free_address(context, &addresses->val[i]); free(addresses->val); addresses->len = 0; addresses->val = NULL; return 0;}/** * krb5_copy_address copies the content of address * inaddr to outaddr. * * @param context a Keberos context * @param inaddr pointer to source address * @param outaddr pointer to destination address * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_copy_address(krb5_context context, const krb5_address *inaddr, krb5_address *outaddr){ struct addr_operations *a = find_af (inaddr->addr_type); if(a != NULL && a->copy_addr != NULL) return (*a->copy_addr)(context, inaddr, outaddr); return copy_HostAddress(inaddr, outaddr);}/** * krb5_copy_addresses copies the content of addresses * inaddr to outaddr. * * @param context a Keberos context * @param inaddr pointer to source addresses * @param outaddr pointer to destination addresses * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_copy_addresses(krb5_context context, const krb5_addresses *inaddr, krb5_addresses *outaddr){ int i; ALLOC_SEQ(outaddr, inaddr->len); if(inaddr->len > 0 && outaddr->val == NULL) return ENOMEM; for(i = 0; i < inaddr->len; i++) krb5_copy_address(context, &inaddr->val[i], &outaddr->val[i]); return 0;}/** * krb5_append_addresses adds the set of addresses in source to * dest. While copying the addresses, duplicates are also sorted out. * * @param context a Keberos context * @param dest destination of copy operation * @param source adresses that are going to be added to dest * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_append_addresses(krb5_context context, krb5_addresses *dest, const krb5_addresses *source){ krb5_address *tmp; krb5_error_code ret; int i; if(source->len > 0) { tmp = realloc(dest->val, (dest->len + source->len) * sizeof(*tmp)); if(tmp == NULL) { krb5_set_error_string(context, "realloc: out of memory"); return ENOMEM; } dest->val = tmp; for(i = 0; i < source->len; i++) { /* skip duplicates */ if(krb5_address_search(context, &source->val[i], dest)) continue; ret = krb5_copy_address(context, &source->val[i], &dest->val[dest->len]); if(ret) return ret; dest->len++; } } return 0;}/** * Create an address of type KRB5_ADDRESS_ADDRPORT from (addr, port) * * @param context a Keberos context * @param res built address from addr/port * @param addr address to use * @param port port to use * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_make_addrport (krb5_context context, krb5_address **res, const krb5_address *addr, int16_t port){ krb5_error_code ret; size_t len = addr->address.length + 2 + 4 * 4; u_char *p; *res = malloc (sizeof(**res)); if (*res == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } (*res)->addr_type = KRB5_ADDRESS_ADDRPORT; ret = krb5_data_alloc (&(*res)->address, len); if (ret) { krb5_set_error_string(context, "malloc: out of memory"); free (*res); *res = NULL; return ret; } p = (*res)->address.data; *p++ = 0; *p++ = 0; *p++ = (addr->addr_type ) & 0xFF; *p++ = (addr->addr_type >> 8) & 0xFF; *p++ = (addr->address.length ) & 0xFF; *p++ = (addr->address.length >> 8) & 0xFF; *p++ = (addr->address.length >> 16) & 0xFF; *p++ = (addr->address.length >> 24) & 0xFF; memcpy (p, addr->address.data, addr->address.length); p += addr->address.length; *p++ = 0; *p++ = 0; *p++ = (KRB5_ADDRESS_IPPORT ) & 0xFF; *p++ = (KRB5_ADDRESS_IPPORT >> 8) & 0xFF; *p++ = (2 ) & 0xFF; *p++ = (2 >> 8) & 0xFF; *p++ = (2 >> 16) & 0xFF; *p++ = (2 >> 24) & 0xFF; memcpy (p, &port, 2); p += 2; return 0;}/** * Calculate the boundary addresses of `inaddr'/`prefixlen' and store * them in `low' and `high'. * * @param context a Keberos context * @param inaddr address in prefixlen that the bondery searched * @param prefixlen width of boundery * @param low lowest address * @param high highest address * * @return Return an error code or 0. * * @ingroup krb5_address */krb5_error_code KRB5_LIB_FUNCTIONkrb5_address_prefixlen_boundary(krb5_context context, const krb5_address *inaddr, unsigned long prefixlen, krb5_address *low, krb5_address *high){ struct addr_operations *a = find_atype (inaddr->addr_type); if(a != NULL && a->mask_boundary != NULL) return (*a->mask_boundary)(context, inaddr, prefixlen, low, high); krb5_set_error_string(context, "Address family %d doesn't support " "address mask operation", inaddr->addr_type); return KRB5_PROG_ATYPE_NOSUPP;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -