Exemplo n.º 1
0
void delete_sock_info(struct socket_info* sock,int proto)
{
  struct socket_info** list;
  list=get_sock_info_list(proto);
  sock_listrm(list, sock);
  free_sock_info(sock);
}
Exemplo n.º 2
0
/* adds a sock_info structure to the corresponding proto list
 * return  0 on success, -1 on error */
int add_listen_iface(char* name, unsigned short port, unsigned short proto,
						enum si_flags flags)
{
	struct socket_info** list;
	unsigned short c_proto;
	
	c_proto=(proto)?proto:PROTO_UDP;
	do{
		list=get_sock_info_list(c_proto);
		if (list==0){
			LOG(L_ERR, "ERROR: add_listen_iface: get_sock_info_list failed\n");
			goto error;
		}
		if (port==0){ /* use default port */
			port=
#ifdef USE_TLS
				((c_proto)==PROTO_TLS)?tls_port_no:
#endif
				port_no;
		}
#ifdef USE_TLS
		else if ((c_proto==PROTO_TLS) && (proto==0)){
			/* -l  ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1? */
			port++;
		}
#endif
		if (new_sock2list(name, port, c_proto, flags, list)<0){
			LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
			goto error;
		}
	}while( (proto==0) && (c_proto=next_proto(c_proto)));
	return 0;
error:
	return -1;
}
Exemplo n.º 3
0
/* checks if the proto: ip:port is one of the address we listen on
 * and returns the corresponding socket_info structure.
 * (same as grep_socket_info, but use ip addr instead)
 * if port==0, the  port number is ignored
 * if proto==0 (PROTO_NONE) the protocol is ignored
 * returns  0 if not found
 * WARNING: uses str2ip6 so it will overwrite any previous
 *  unsaved result of this function (static buffer)
 */
struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
												unsigned short proto)
{
	struct socket_info* si;
	struct socket_info** list;
	unsigned short c_proto;
	
	c_proto=proto?proto:PROTO_UDP;
	do{
		/* get the proper sock_list */
		if (c_proto==PROTO_NONE)
			list=&udp_listen;
		else
			list=get_sock_info_list(c_proto);
	
		if (list==0){
			LOG(L_WARN, "WARNING: grep_sock_info: "
						"unknown proto %d\n", c_proto);
			goto not_found; /* false */
		}
		for (si=*list; si; si=si->next){
			if (port) {
				if (si->port_no!=port) {
					continue;
				}
			}
			if (ip_addr_cmp(ip, &si->address))
				goto found;
		}
	}while( (proto==0) && (c_proto=next_proto(c_proto)) );
not_found:
	return 0;
found:
	return si;
}
Exemplo n.º 4
0
void print_all_socket_lists()
{
	struct socket_info *si;
	struct socket_info** list;
	unsigned short proto;
	
	
	proto=PROTO_UDP;
	do{
		list=get_sock_info_list(proto);
		for(si=list?*list:0; si; si=si->next){
			printf("             %s: %s [%s]:%s%s\n", get_proto_name(proto),
			       si->name.s, si->address_str.s, si->port_no_str.s, 
			       si->flags & SI_IS_MCAST ? " mcast" : "");
		}
	}while((proto=next_proto(proto)));
}
Exemplo n.º 5
0
/*
 * RPC command to list the listening sockets
 */
static void corex_rpc_list_sockets(rpc_t* rpc, void* ctx)
{
	void* th;
	void* ih;

	struct socket_info *si;
	struct socket_info** list;
	struct addr_info* ai;
	unsigned short proto;
	
	proto=PROTO_UDP;
	do {
		list=get_sock_info_list(proto);
		for(si=list?*list:0; si; si=si->next)
		{
			/* add structure node */
			if (rpc->add(ctx, "{", &th) < 0)
			{
				rpc->fault(ctx, 500, "Internal error socket structure");
				return;
			}

			if(rpc->struct_add(th, "ss{",
				"PROTO", 	get_valid_proto_name(proto),
				"NAME", 	si->name.s,
				"ADDRLIST",  &ih)<0)
			{
				rpc->fault(ctx, 500, "Internal error address list structure");
				return;
			}

			if(rpc->struct_add(ih, "s", "ADDR", si->address_str.s)<0)
			{
				rpc->fault(ctx, 500, "Internal error address structure");
				return;
			}
	
			if (si->addr_info_lst)
			{

				for (ai=si->addr_info_lst; ai; ai=ai->next)
				{
					if(rpc->struct_add(ih, "s", "ADDR", ai->address_str.s)<0)
					{
						rpc->fault(ctx, 500,
								"Internal error extra address structure");
						return;
					}

				}
			}

			if(rpc->struct_add(th, "ssss",
					"PORT", si->port_no_str.s,
					"MCAST", si->flags & SI_IS_MCAST ? "yes" : "no",
					"MHOMED", si->flags & SI_IS_MHOMED? "yes" : "no",
					"ADVERTISE", si->useinfo.name.s?si->useinfo.name.s:"-")<0)
			{
				rpc->fault(ctx, 500, "Internal error attrs structure");
				return;
			}
		}
	} while((proto=next_proto(proto)));

	return;
}
Exemplo n.º 6
0
/*!
 * This function will retrieve a list of all ip addresses and ports that Kamailio
 * is listening on, with respect to the transport protocol specified with
 * 'protocol'. This function supports both IPv4 and IPv6
 *
 * The first parameter, ipList, is a pointer to a pointer. It will be assigned a
 * new block of memory holding the IP Addresses and ports being listened to with
 * respect to 'protocol'.  The array maps a 2D array into a 1 dimensional space,
 * and is layed out as follows:
 *
 * The first NUM_IP_OCTETS indices will be the IP address, and the next index
 * the port.  So if NUM_IP_OCTETS is equal to 4 and there are two IP addresses
 * found, then:
 *
 *  - ipList[0] will be the first octet of the first ip address
 *  - ipList[3] will be the last octet of the first ip address.
 *  - iplist[4] will be the port of the first ip address
 *  -
 *  - iplist[5] will be the first octet of the first ip address,
 *  - and so on.
 */
int get_socket_list_from_proto_and_family(int **ipList, int protocol, int family) {

    struct socket_info  *si;
    struct socket_info** list;

    int num_ip_octets   = family == AF_INET ? NUM_IP_OCTETS : NUM_IPV6_OCTETS;
    int numberOfSockets = 0;
    int currentRow      = 0;

    /* I hate to use #ifdefs, but this is necessary because of the way
     * get_sock_info_list() is defined.  */
#ifndef USE_TCP
    if (protocol == PROTO_TCP)
    {
        return 0;
    }
#endif

#ifndef USE_TLS
    if (protocol == PROTO_TLS)
    {
        return 0;
    }
#endif
#ifndef USE_SCTP
    if (protocol == PROTO_SCTP)
    {
        return 0;
    }
#endif
    /* We have no "interfaces" for websockets */
    if (protocol == PROTO_WS || protocol == PROTO_WSS)
        return 0;

    /* Retrieve the list of sockets with respect to the given protocol. */
    list=get_sock_info_list(protocol);

    /* Find out how many sockets are in the list.  We need to know this so
     * we can malloc an array to assign to ipList. */
    for(si=list?*list:0; si; si=si->next) {
        if (si->address.af == family) {
            numberOfSockets++;
        }
    }

    /* There are no open sockets with respect to the given protocol. */
    if (numberOfSockets == 0)
    {
        return 0;
    }

    *ipList = pkg_malloc(numberOfSockets * (num_ip_octets + 1) * sizeof(int));

    /* We couldn't allocate memory for the IP List.  So all we can do is
     * fail. */
    if (*ipList == NULL) {
        LM_ERR("no more pkg memory");
        return 0;
    }


    /* We need to search the list again.  So find the front of the list. */
    list=get_sock_info_list(protocol);

    /* Extract out the IP Addresses and ports.  */
    for(si=list?*list:0; si; si=si->next) {
        int i;

        /* We currently only support IPV4. */
        if (si->address.af != family) {
            continue;
        }

        for (i = 0; i < num_ip_octets; i++) {
            (*ipList)[currentRow*(num_ip_octets + 1) + i ] =
                si->address.u.addr[i];
        }
        (*ipList)[currentRow*(num_ip_octets + 1) + i] =
            si->port_no;

        currentRow++;
    }

    return numberOfSockets;
}
Exemplo n.º 7
0
/* checks if the proto: host:port is one of the address we listen on
 * and returns the corresponding socket_info structure.
 * if port==0, the  port number is ignored
 * if proto==0 (PROTO_NONE) the protocol is ignored
 * returns  0 if not found
 * WARNING: uses str2ip6 so it will overwrite any previous
 *  unsaved result of this function (static buffer)
 */
struct socket_info* grep_sock_info(str* host, unsigned short port,
												unsigned short proto)
{
	char* hname;
	int h_len;
	struct socket_info* si;
	struct socket_info** list;
	unsigned short c_proto;
#ifdef USE_IPV6
	struct ip_addr* ip6;
#endif
	h_len=host->len;
	hname=host->s;
#ifdef USE_IPV6
	if ((h_len>2)&&((*hname)=='[')&&(hname[h_len-1]==']')){
		/* ipv6 reference, skip [] */
		hname++;
		h_len-=2;
	}
#endif
	c_proto=proto?proto:PROTO_UDP;
	do{
		/* get the proper sock_list */
		if (c_proto==PROTO_NONE)
			list=&udp_listen;
		else
			list=get_sock_info_list(c_proto);
	
		if (list==0){
			LOG(L_WARN, "WARNING: grep_sock_info: "
						"unknown proto %d\n", c_proto);
			goto not_found; /* false */
		}
		for (si=*list; si; si=si->next){
			DBG("grep_sock_info - checking if host==us: %d==%d && "
					" [%.*s] == [%.*s]\n", 
						h_len,
						si->name.len,
						h_len, hname,
						si->name.len, si->name.s
				);
			if (port) {
				DBG("grep_sock_info - checking if port %d matches port %d\n", 
						si->port_no, port);
				if (si->port_no!=port) {
					continue;
				}
			}
			if ( (h_len==si->name.len) && 
				(strncasecmp(hname, si->name.s,
						 si->name.len)==0) /*slower*/)
				/* comp. must be case insensitive, host names
				 * can be written in mixed case, it will also match
				 * ipv6 addresses if we are lucky*/
				goto found;
		/* check if host == ip address */
#ifdef USE_IPV6
			/* ipv6 case is uglier, host can be [3ffe::1] */
			ip6=str2ip6(host);
			if (ip6){
				if (ip_addr_cmp(ip6, &si->address))
					goto found; /* match */
				else
					continue; /* no match, but this is an ipv6 address
								 so no point in trying ipv4 */
			}
#endif
			/* ipv4 */
			if ( 	(!(si->flags&SI_IS_IP)) &&
					(h_len==si->address_str.len) && 
				(memcmp(hname, si->address_str.s, 
									si->address_str.len)==0)
				)
				goto found;
		}
	}while( (proto==0) && (c_proto=next_proto(c_proto)) );
not_found:
	return 0;
found:
	return si;
}
Exemplo n.º 8
0
/*
 * This function will retrieve a list of all ip addresses and ports that OpenSER
 * is listening on, with respect to the transport protocol specified with
 * 'protocol'. 
 *
 * The first parameter, ipList, is a pointer to a pointer. It will be assigned a
 * new block of memory holding the IP Addresses and ports being listened to with
 * respect to 'protocol'.  The array maps a 2D array into a 1 dimensional space,
 * and is layed out as follows:
 *
 * The first NUM_IP_OCTETS indices will be the IP address, and the next index
 * the port.  So if NUM_IP_OCTETS is equal to 4 and there are two IP addresses
 * found, then:
 *
 *  - ipList[0] will be the first octet of the first ip address
 *  - ipList[3] will be the last octet of the first ip address.
 *  - iplist[4] will be the port of the first ip address
 *  - 
 *  - iplist[5] will be the first octet of the first ip address, 
 *  - and so on.  
 *
 * The function will return the number of sockets which were found.  This can be
 * used to index into ipList.
 *
 * NOTE: This function assigns a block of memory equal to:
 *
 *            returnedValue * (NUM_IP_OCTETS + 1) * sizeof(int);
 *
 *       Therefore it is CRUCIAL that you free ipList when you are done with its
 *       contents, to avoid a nasty memory leak.
 */
int get_socket_list_from_proto(int **ipList, int protocol) {

	struct socket_info  *si;
	struct socket_info** list;

	int num_ip_octets   = 4;
	int numberOfSockets = 0;
	int currentRow      = 0;

	/* I hate to use #ifdefs, but this is necessary because of the way 
	 * get_sock_info_list() is defined.  */
#ifndef USE_TCP
	if (protocol == PROTO_TCP) 
	{
		return 0;
	}
#endif

#ifndef USE_TLS
	if (protocol == PROTO_TLS)
	{
		return 0;
	}
#endif

	/* Retrieve the list of sockets with respect to the given protocol. */
	list=get_sock_info_list(protocol);

	/* Find out how many sockets are in the list.  We need to know this so
	 * we can malloc an array to assign to ipList. */
	for(si=list?*list:0; si; si=si->next){
		/* We only support IPV4 at this point. */
		if (si->address.af == AF_INET) {
			numberOfSockets++;
		}
	}

	/* There are no open sockets with respect to the given protocol. */
	if (numberOfSockets == 0)
	{
		return 0;
	}

	*ipList = pkg_malloc(numberOfSockets * (num_ip_octets + 1) * sizeof(int));

	/* We couldn't allocate memory for the IP List.  So all we can do is
	 * fail. */
	if (*ipList == NULL) {
		LM_ERR("no more pkg memory");
		return 0;
	}


	/* We need to search the list again.  So find the front of the list. */
	list=get_sock_info_list(protocol);

	/* Extract out the IP Addresses and ports.  */
	for(si=list?*list:0; si; si=si->next){

		/* We currently only support IPV4. */
		if (si->address.af != AF_INET) {
			continue;
		}

		(*ipList)[currentRow*(num_ip_octets + 1)  ] = 
			si->address.u.addr[0];
		(*ipList)[currentRow*(num_ip_octets + 1)+1] = 
			si->address.u.addr[1];
		(*ipList)[currentRow*(num_ip_octets + 1)+2] = 
			si->address.u.addr[2];
		(*ipList)[currentRow*(num_ip_octets + 1)+3] = 
			si->address.u.addr[3];
		(*ipList)[currentRow*(num_ip_octets + 1)+4] = 
			si->port_no;
		
		currentRow++;
	}

	return numberOfSockets;
}