struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type) { struct ast_str *string = ast_str_alloca(64); if (!string) { return NULL; } ast_str_set(&string, 0, (ast_sockaddr_is_ipv4(addr) || ast_sockaddr_is_ipv4_mapped(addr)) ? "IPV4/" : "IPV6/"); if (transport_type) { char *transport_string = NULL; /* NOTE: None will be applied if multiple transport types are specified in transport_type */ switch(transport_type) { case AST_TRANSPORT_UDP: transport_string = "UDP"; break; case AST_TRANSPORT_TCP: transport_string = "TCP"; break; case AST_TRANSPORT_TLS: transport_string = "TLS"; break; case AST_TRANSPORT_WS: transport_string = "WS"; break; case AST_TRANSPORT_WSS: transport_string = "WSS"; break; } if (transport_string) { ast_str_append(&string, 0, "%s/", transport_string); } } ast_str_append(&string, 0, "%s", ast_sockaddr_stringify_addr(addr)); ast_str_append(&string, 0, "/%s", ast_sockaddr_stringify_port(addr)); return ast_json_string_create(ast_str_buffer(string)); }
static void dump_addr(char *output, int maxlen, void *value, int len) { struct ast_sockaddr addr; if (len == (int)sizeof(struct sockaddr_in)) { addr.ss.ss_family = AF_INET; } else if (len == (int) sizeof(struct sockaddr_in6)) { addr.ss.ss_family = AF_INET6; } else { ast_copy_string(output, "Invalid Address", maxlen); return; } memcpy(&addr, value, len); addr.len = len; snprintf(output, maxlen, "%s %s", ast_sockaddr_is_ipv4(&addr) || ast_sockaddr_is_ipv4_mapped(&addr) ? "IPV4" : "IPV6", ast_sockaddr_stringify(&addr)); }
/*! \brief Function which negotiates an incoming media stream */ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream) { struct t38_state *state; char host[NI_MAXHOST]; RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free); if (!session->endpoint->media.t38.enabled) { ast_debug(3, "Declining; T.38 not enabled on session\n"); return -1; } if (!(state = t38_state_get_or_alloc(session))) { return -1; } if ((session->t38state == T38_REJECTED) || (session->t38state == T38_DISABLED)) { ast_debug(3, "Declining; T.38 state is rejected or declined\n"); t38_change_state(session, session_media, state, T38_DISABLED); return -1; } ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host)); /* Ensure that the address provided is valid */ if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_INET) <= 0) { /* The provided host was actually invalid so we error out this negotiation */ ast_debug(3, "Declining; provided host is invalid\n"); return -1; } /* Check the address family to make sure it matches configured */ if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->media.t38.ipv6) || (ast_sockaddr_is_ipv4(addrs) && session->endpoint->media.t38.ipv6)) { /* The address does not match configured */ ast_debug(3, "Declining, provided host does not match configured address family\n"); return -1; } return 1; }
int ast_sockaddr_is_any(const struct ast_sockaddr *addr) { union { struct sockaddr_storage ss; struct sockaddr_in sin; struct sockaddr_in6 sin6; } tmp_addr = { .ss = addr->ss, }; return (ast_sockaddr_is_ipv4(addr) && (tmp_addr.sin.sin_addr.s_addr == INADDR_ANY)) || (ast_sockaddr_is_ipv6(addr) && IN6_IS_ADDR_UNSPECIFIED(&tmp_addr.sin6.sin6_addr)); } int ast_sockaddr_hash(const struct ast_sockaddr *addr) { /* * For IPv4, return the IP address as-is. For IPv6, return the last 32 * bits. */ switch (addr->ss.ss_family) { case AF_INET: return ((const struct sockaddr_in *)&addr->ss)->sin_addr.s_addr; case AF_INET6: return ((uint32_t *)&((const struct sockaddr_in6 *)&addr->ss)->sin6_addr)[3]; default: ast_log(LOG_ERROR, "Unknown address family '%d'.\n", addr->ss.ss_family); return 0; } } int ast_accept(int sockfd, struct ast_sockaddr *addr) { addr->len = sizeof(addr->ss); return accept(sockfd, (struct sockaddr *)&addr->ss, &addr->len); }