Exemple #1
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_validate_config                                              *
 *                                                                            *
 * Purpose: validate configuration parameters                                 *
 *                                                                            *
 * Author: Vladimir Levijev                                                   *
 *                                                                            *
 ******************************************************************************/
static void	zbx_validate_config(void)
{
	if ((NULL == CONFIG_JAVA_GATEWAY || '\0' == *CONFIG_JAVA_GATEWAY) && CONFIG_JAVAPOLLER_FORKS > 0)
	{
		zabbix_log(LOG_LEVEL_CRIT, "\"JavaGateway\" configuration parameter is not specified or empty");
		exit(EXIT_FAILURE);
	}

	if (0 != CONFIG_VALUE_CACHE_SIZE && 128 * ZBX_KIBIBYTE > CONFIG_VALUE_CACHE_SIZE)
	{
		zabbix_log(LOG_LEVEL_CRIT, "\"ValueCacheSize\" configuration parameter must be either 0"
				" or greater than 128KB");
		exit(EXIT_FAILURE);
	}

	if (NULL != CONFIG_SOURCE_IP && ('\0' == *CONFIG_SOURCE_IP || SUCCEED != is_ip(CONFIG_SOURCE_IP)))
	{
		zabbix_log(LOG_LEVEL_CRIT, "invalid \"SourceIP\" configuration parameter: '%s'", CONFIG_SOURCE_IP);
		exit(EXIT_FAILURE);
	}
#if !defined(HAVE_LIBXML2) || !defined(HAVE_LIBCURL)
	if (0 != CONFIG_VMWARE_FORKS)
	{
		zabbix_log(LOG_LEVEL_CRIT, "cannot start vmware collector because Zabbix server is built without VMware"
				" support");
		exit(EXIT_FAILURE);
	}
#endif
}
Exemple #2
0
static int
dns_resolver_instantiate(struct key *key, const void *data,
                         size_t datalen)
{
    int rc = 0;
    char *ip;

    ip = kmalloc(datalen + 1, GFP_KERNEL);
    if (!ip)
        return -ENOMEM;

    memcpy(ip, data, datalen);
    ip[datalen] = '\0';

    /* make sure this looks like an address */
    if (!is_ip((const char *) ip)) {
        kfree(ip);
        return -EINVAL;
    }

    key->type_data.x[0] = datalen;
    key->payload.data = ip;

    return rc;
}
Exemple #3
0
static char *ia_resolv(iaddr ia) {
    int err;
    err = getnameinfo((struct sockaddr*)&ia,sizeof(ia),query,sizeof(query),0,0,0);

    if(err==0) { // all fine, no error

        if( is_ip(query) ) return(query);

        // is it an hostname?
        char *name = strtok(query,".");
        // then remove the domain part
        if(name==NULL) name=&query[0];
        return(name);

    } else { // check for errors and try to overcome them
        fprintf(stderr,"Error in getnameinfo: %s\n",
                strerror(errno));
        // however we try harder to return the ip
        if(inet_ntop(ia.af, &ia.u, query, sizeof query)==NULL) {
            fprintf(stderr,"Error in inet_ntop: %s\n",
                    strerror(errno));
            return NULL;
        }
        return (&query[0]);
    }
    // this never gets here
}
Exemple #4
0
unsigned long getaddress(char *host) {
	struct hostent* pent;
	long l, *lp;

	if (is_ip(host))
		return inet_addr(host);

	/* try the system's own resolution mechanism for dns lookup:
	 required only for domain names.
	 inspite of what the rfc2543 :D Using SRV DNS Records recommends,
	 we are leaving it to the operating system to do the name caching.

	 this is an important implementational issue especially in the light
	 dynamic dns servers like dynip.com or dyndns.com where a dial
	 ip address is dynamically assigned a sub domain like farhan.dynip.com

	 although expensive, this is a must to allow OS to take
	 the decision to expire the DNS records as it deems fit.
	*/
	pent = gethostbyname(host);
	if (!pent) {
		printf("'%s' is unresolveable\n", host);
		exit_code(2);
	}
	lp = (long *) (pent->h_addr);
	l = *lp;
	return l;
}
Exemple #5
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_validate_config                                              *
 *                                                                            *
 * Purpose: validate configuration parameters                                 *
 *                                                                            *
 * Author: Alexei Vladishev, Rudolfs Kreicbergs                               *
 *                                                                            *
 ******************************************************************************/
static void	zbx_validate_config(void)
{
	char	*ch_error;

	if (NULL == CONFIG_HOSTNAME)
	{
		zabbix_log(LOG_LEVEL_CRIT, "\"Hostname\" configuration parameter is not defined");
		exit(EXIT_FAILURE);
	}

	if (FAIL == zbx_check_hostname(CONFIG_HOSTNAME, &ch_error))
	{
		zabbix_log(LOG_LEVEL_CRIT, "invalid \"Hostname\" configuration parameter '%s': %s", CONFIG_HOSTNAME,
				ch_error);
		zbx_free(ch_error);
		exit(EXIT_FAILURE);
	}

	if (0 == CONFIG_UNREACHABLE_POLLER_FORKS && 0 != CONFIG_POLLER_FORKS + CONFIG_IPMIPOLLER_FORKS +
			CONFIG_JAVAPOLLER_FORKS)
	{
		zabbix_log(LOG_LEVEL_CRIT, "\"StartPollersUnreachable\" configuration parameter must not be 0"
				" if regular, IPMI or Java pollers are started");
		exit(EXIT_FAILURE);
	}

	if ((NULL == CONFIG_JAVA_GATEWAY || '\0' == *CONFIG_JAVA_GATEWAY) && 0 < CONFIG_JAVAPOLLER_FORKS)
	{
		zabbix_log(LOG_LEVEL_CRIT, "\"JavaGateway\" configuration parameter is not specified or empty");
		exit(EXIT_FAILURE);
	}

	if (ZBX_PROXYMODE_ACTIVE == CONFIG_PROXYMODE &&	NULL == CONFIG_SERVER)
	{
		zabbix_log(LOG_LEVEL_CRIT, "\"Server\" configuration parameter is not defined."
				" This parameter is mandatory for active proxies.");
		exit(EXIT_FAILURE);
	}

	if (NULL != CONFIG_SOURCE_IP && ('\0' == *CONFIG_SOURCE_IP || SUCCEED != is_ip(CONFIG_SOURCE_IP)))
	{
		zabbix_log(LOG_LEVEL_CRIT, "invalid \"SourceIP\" configuration parameter: '%s'", CONFIG_SOURCE_IP);
		exit(EXIT_FAILURE);
	}

#if !defined(HAVE_LIBXML2) || !defined(HAVE_LIBCURL)
	if (0 != CONFIG_VMWARE_FORKS)
	{
		zabbix_log(LOG_LEVEL_CRIT, "cannot start vmware collector because Zabbix proxy is built without VMware"
				" support");
		exit(EXIT_FAILURE);
	}
#endif
}
Exemple #6
0
static int find_allowdeny(request_rec *r, array_header *a, int method)
{
    allowdeny *ap = (allowdeny *) a->elts;
    int mmask = (1 << method);
    int i;
    int gothost = 0;
    const char *remotehost = NULL;

    for (i = 0; i < a->nelts; ++i) {
	if (!(mmask & ap[i].limited))
	    continue;

	switch (ap[i].type) {
	case T_ENV:
	    if (ap_table_get(r->subprocess_env, ap[i].x.from)) {
		return 1;
	    }
	    break;

	case T_ALL:
	    return 1;

	case T_IP:
	    if (ap[i].x.ip.net.s_addr != INADDR_NONE
		&& (r->connection->remote_addr.sin_addr.s_addr
		    & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
		return 1;
	    }
	    break;

	case T_HOST:
	    if (!gothost) {
		remotehost = ap_get_remote_host(r->connection, r->per_dir_config,
					    REMOTE_DOUBLE_REV);

		if ((remotehost == NULL) || is_ip(remotehost))
		    gothost = 1;
		else
		    gothost = 2;
	    }

	    if ((gothost == 2) && in_domain(ap[i].x.from, remotehost))
		return 1;
	    break;

	case T_FAIL:
	    /* do nothing? */
	    break;
	}
    }

    return 0;
}
Exemple #7
0
static int get_cert(socket_st *hd, const char *hostname, unsigned udp, int fd)
{
	gnutls_certificate_credentials_t xcred;
	gnutls_session_t session;
	int ret;
	struct priv_st priv;

	priv.found = 0;
	priv.fd = fd;

	ret = gnutls_certificate_allocate_credentials(&xcred);
	if (ret < 0) {
		fprintf(stderr, "error[%d]: %s\n", __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	gnutls_certificate_set_verify_function(xcred, cert_callback);

	ret = gnutls_init(&session, (udp?GNUTLS_DATAGRAM:0)|GNUTLS_CLIENT);
	if (ret < 0) {
		fprintf(stderr, "error[%d]: %s\n", __LINE__,
			gnutls_strerror(ret));
		exit(1);
	}
	gnutls_session_set_ptr(session, &priv);
	gnutls_transport_set_int(session, hd->fd);

	gnutls_set_default_priority(session);
	if (hostname && is_ip(hostname)==0) {
		gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, strlen(hostname));
	}
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);

	do {
		ret = gnutls_handshake(session);
	} while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED);
	/* we don't care on the result */

	gnutls_deinit(session);
	gnutls_certificate_free_credentials(xcred);

	if (priv.found == 0)
		return -1;

	return 0;
}
Exemple #8
0
Link* Link::connect(const char *host, int port){
	Link *link;
	int sock = -1;

	char ip_resolve[INET_ADDRSTRLEN];
	if(!is_ip(host)){
		struct hostent *hptr = gethostbyname(host);
		for(int i=0; hptr && hptr->h_addr_list[i] != NULL; i++){
			struct in_addr *addr = (struct in_addr *)hptr->h_addr_list[i];
			if(inet_ntop(AF_INET, addr, ip_resolve, sizeof(ip_resolve))){
				//printf("resolve %s: %s\n", host, ip_resolve);
				host = ip_resolve;
				break;
			}
		}
	}

	struct sockaddr_in addr;
	bzero(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons((short)port);
	inet_pton(AF_INET, host, &addr.sin_addr);

	if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){
		goto sock_err;
	}
	if(::connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
		goto sock_err;
	}

	//log_debug("fd: %d, connect to %s:%d", sock, ip, port);
	link = new Link();
	link->sock = sock;
	link->keepalive(true);
	return link;
sock_err:
	//log_debug("connect to %s:%d failed: %s", ip, port, strerror(errno));
	if(sock >= 0){
		::close(sock);
	}
	return NULL;
}
Exemple #9
0
        void add_point( std::string const &name )
        {
            auto info = utilities::get_endpoint_info( name );
            if( !info.is_ip( ) ) {
                LOGERR << "Endpoint format'" << name << "' is not valid";
                return;
            }

            try {

                auto addr = bip::address::from_string( info.addpess );

                bip::udp::endpoint listen_ep (
                            bip::address::from_string( addr.is_v6( )
                                                        ? any_ipv6
                                                        : any_ipv4 ),
                            info.service );

                LOGINF << "Adding endpoint '" << name << "'; "
                       << ( addr.is_v6( ) ? "ipv6" : "ipv4" )
                       << "; port: " << info.service;

                auto pinfo = std::make_shared<point_info>
                                ( app_->get_io_service( ), 256 );

                pinfo->sock.open( addr.is_v6( )
                                  ? bip::udp::v6( )
                                  : bip::udp::v4( ) );

                pinfo->sock.set_option( mcast_socket::reuse_address(true) );
                pinfo->sock.set_option( bip::multicast::join_group( addr ) );
                pinfo->sock.bind( listen_ep );
                {
                    std::lock_guard<std::mutex> l(points_lock_);
                    points_[name] = pinfo;
                }
                LOGDBG << "Store endpoint " << name << ". Ok";
            } catch( const std::exception &ex ) {
                LOGERR << "Add endpoint '" << name
                       << "' failed: " << ex.what( );
            }
        }
Exemple #10
0
static void
option_parse(int argc, void *argv)
{
	int ch;

	while ((ch = getopt(argc, argv, "df:hi:m:n:ps:t:E:PS:")) != -1) {
		switch (ch) {
		case 'd':	/* Set the output format = txt */
			query.outfmt = DEBUG;
			query.basis = BYTE;
			break;
		case 'f':	/* Filter */
			if (!is_ip(optarg, &query.inflow))
				usage();
			break;
		case 'h':
			usage();
			break;
		case 'i':
			query.aggr_interval = strtol(optarg, NULL, 10);
			break;
		case 'm':
			if (!strncmp(optarg, "byte", 4))
				query.basis = BYTE;
			else if (!strncmp(optarg, "packet", 6))
				query.basis = PACKET;
			else
				usage();
			break;
		case 'n':
			if (optarg[0] == '-')
				usage();
			query.nflow = strtol(optarg, NULL, 10);
			break;
		case 'p':	/* Set the output format = json */
			/* If -d and -p are input at the same time, use -d */
			if (query.outfmt != DEBUG) {
				query.outfmt = JSON;
				query.basis  = BYTE;
			}
			break;
		case 's':
			if (optarg[0] == '-')
				usage();
			query.total_duration = strtol(optarg, NULL, 10);
			break;
		case 't':
			if (optarg[0] == '-')
				usage();
			query.threshold = strtod(optarg, NULL);
			break;
		case 'E':
			if (optarg[0] == '-')
				usage();
			query.end_time = strtol(optarg, NULL, 10);
			break;
		case 'P':
			query.view = PROTO_VIEW;
			break;
		case 'S':
			if (optarg[0] == '-')
				usage();
			query.start_time = strtol(optarg, NULL, 10);
			break;
		default:
			usage();
			break;
		}
	}
}
Exemple #11
0
int main(int argc, char *argv[])
{
	FILE	*pf;
	char	buff[BUFSIZE];
	int		c, i, port;
	unsigned int tsp;
	char	*scheme, *user, *host, *backup;
	pid_t 	pid;
	struct 	timespec ts;
	int 	upp;

#ifdef HAVE_GETOPT_LONG
	int option_index = 0;
	static struct option l_opts[] = {
		{"help", 0, 0, 'X'},
		{"version", 0, 0, 'V'},
		{"filename", 1, 0, 'f'},
		{"sip-uri", 1, 0, 's'},
		{"traceroute-mode", 0, 0, 'T'},
		{"usrloc-mode", 0, 0, 'U'},
		{"invite-mode", 0, 0, 'I'},
		{"message-mode", 0, 0, 'M'},
		{"contact", 1, 0, 'C'},
		{"appendix-begin", 1, 0, 'b'},
		{"appendix-end", 1, 0, 'e'},
		{"sleep", 1, 0, 'o'},
		{"expires", 1, 0, 'x'},
		{"remove-bindings", 1, 0, 'z'},
		{"flood-mode", 0, 0, 'F'},
		{"random-mode", 0, 0, 'R'},
		{"trash-chars", 1, 0, 't'},
		{"local-port", 1, 0, 'l'},
		{"remote-port", 1, 0, 'r'},
		{"outbound-proxy", 1, 0, 'p'},
		{"hostname", 1, 0, 'H'},
		{"max-fowards", 1, 0, 'm'},
		{"numeric", 0, 0, 'n'},
		{"no-via", 0, 0, 'i'},
		{"password", 1, 0, 'a'},
		{"ignore-redirects", 0, 0, 'd'},
		{"verbose", 0, 0, 'v'},
		{"extract-ip", 0, 0, 'w'},
		{"replace-string", 0, 0, 'g'},
		{"replace", 0, 0, 'G'},
		{"nagios-code", 0, 0, 'N'},
		{"nagios-warn", 1, 0, 'W'},
		{"search", 1, 0, 'q'},
		{"message-body", 1, 0, 'B'},
		{"disposition", 1, 0, 'O'},
		{"processes", 1, 0, 'P'},
		{"auth-username", 1, 0, 'u'},
		{"no-crlf", 0, 0, 'L'},
		{"timing", 1, 0, 'A'},
		{"symmetric", 0, 0, 'S'},
		{"from", 1, 0, 'c'},
		{"timeout-factor", 1, 0, 'D'},
		{"transport", 1, 0, 'E'},
		{"headers", 1, 0, 'j'},
		{0, 0, 0, 0}
	};
#endif
	/* some initialisation to be shure */
	file_b=uri_b=trace=lport=usrloc=flood=verbose=randtrash=trashchar = 0;
	warning_ext=rand_rem=nonce_count=replace_b=invite=message = 0;
	sleep_ms=empty_contact=nagios_warn=timing=outbound_proxy=symmetric = 0;
	namebeg=nameend=maxforw= -1;
	numeric=via_ins=redirects=fix_crlf=processes = 1;
	username=password=replace_str=hostname=contact_uri=mes_body = NULL;
	con_dis=auth_username=from_uri=headers = NULL;
	scheme = user = host = backup = req = rep = rec = NULL;
	re = NULL;
	address= 0;
	transport=tsp = 0;
	rport = port = 0;
	expires_t = USRLOC_EXP_DEF;
	inv_final = 64 * SIP_T1;
	memset(buff, 0, BUFSIZE);
	memset(fqdn, 0, FQDN_SIZE);

	if (argc==1) {
		print_help();
	}

	/* lots of command line switches to handle*/
#ifdef HAVE_GETOPT_LONG
	while ((c=getopt_long(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:Xz:", l_opts, &option_index)) != EOF){
#else
	while ((c=getopt(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:z:")) != EOF){
#endif
		switch(c){
			case 'a':
				if (strlen(optarg) == 1 && STRNCASECMP(optarg, "-", 1) == 0) {
					password = str_alloc(SIPSAK_MAX_PASSWD_LEN);
					printf("Please enter the password (max. length %i): ", SIPSAK_MAX_PASSWD_LEN);
					if (read_stdin(password, SIPSAK_MAX_PASSWD_LEN, 1) == 0) {
						exit_code(0);
					}
				}
				else {
					password=str_alloc(strlen(optarg) + 1);
					strncpy(password, optarg, strlen(optarg));
				}
				break;
			case 'A':
				timing=str_to_int(optarg);
				break;
			case 'b':
				namebeg=str_to_int(optarg);
				break;
			case 'B':
				mes_body=str_alloc(strlen(optarg) + 1);
				strncpy(mes_body, optarg, strlen(optarg));
				break;
			case 'c':
				backup=str_alloc(strlen(optarg)+1);
				strncpy(backup, optarg, strlen(optarg));
				parse_uri(backup, &scheme, &user, &host, &port);
				if (scheme  == NULL) {
					fprintf(stderr, "error: missing scheme in From URI\n");
					exit_code(2);
				}
				else if (user == NULL) {
					fprintf(stderr, "error: missing username in From URI\n");
					exit_code(2);
				}
				else if (host == NULL) {
					fprintf(stderr, "error: missing host in From URI\n");
					exit_code(2);
				}
				else {
					from_uri=str_alloc(strlen(optarg)+1);
					strncpy(from_uri, optarg, strlen(optarg));
				}
				free(backup);
				break;
			case 'C':
				if ((strlen(optarg) == 5 && STRNCASECMP(optarg, "empty", 5) == 0) || 
					(strlen(optarg) == 4 && STRNCASECMP(optarg, "none", 4) == 0)) {
					empty_contact = 1;
				}
				else if (strlen(optarg) == 1 && STRNCASECMP(optarg, "*", 1) == 0) {
					contact_uri=str_alloc(strlen(optarg)+1);
					strncpy(contact_uri, optarg, strlen(optarg));
				}
				else {
					backup=str_alloc(strlen(optarg)+1);
					strncpy(backup, optarg, strlen(optarg));
					parse_uri(backup, &scheme, &user, &host, &port);
					if (scheme == NULL) {
					    fprintf(stderr, "error: REGISTER Contact uri doesn't not contain "
						   "sip:, sips:, *, or is not empty\n");
				    	exit_code(2);
					}
					else if (user == NULL) {
						fprintf(stderr, "error: missing username in Contact uri\n");
						exit_code(2);
					}
					else if (host == NULL) {
						fprintf(stderr, "error: missing host in Contact uri\n");
						exit_code(2);
					}
					else {
						contact_uri=str_alloc(strlen(optarg)+1);
						strncpy(contact_uri, optarg, strlen(optarg));
					}
					free(backup);
				}
				break;
			case 'd':
				redirects=0;
				break;
			case 'D':
				inv_final = str_to_int(optarg) * SIP_T1;
				break;
			case 'e':
				nameend=str_to_int(optarg);
				break;
			case 'E':
				if (strlen(optarg) == 3 && 
					STRNCASECMP(optarg, "udp", 3) == 0) {
					transport = SIP_UDP_TRANSPORT;
				}
				else if (strlen(optarg) == 3 &&
						STRNCASECMP(optarg, "tcp", 3) == 0) {
					transport = SIP_TCP_TRANSPORT;
				}
				else if (strlen(optarg) == 3 &&
						STRNCASECMP(optarg, "tls", 3) == 0) {
					fprintf(stderr, "error: TLS is not supported yet, supported values: udp, tcp\n");
					exit_code(2);
					transport = SIP_TLS_TRANSPORT;
				}
				else {
					fprintf(stderr, "error: unsupported transport '%s', supported values: udp, tcp\n", optarg);
					exit_code(2);
				}
				break;
			case 'F':
				flood=1;
				break;
			case 'f':
				if (strlen(optarg) != 1 && STRNCASECMP(optarg, "-", 1) != 0) {
					/* file is opened in binary mode so that the cr-lf is 
					   preserved */
					pf = fopen(optarg, "rb");
					if (!pf){
						fprintf(stderr, "error: unable to open the file '%s'.\n", optarg);
						exit_code(2);
					}
					if (fread(buff, 1, sizeof(buff), pf) >= sizeof(buff)){
						fprintf(stderr, "error:the file is too big. try files of less "
							"than %i bytes.\n", BUFSIZE);
						fprintf(stderr, "      or recompile the program with bigger "
							"BUFSIZE defined.\n");
						exit_code(2);
					}
					fclose(pf);
				}
				else if (strlen(optarg) == 1 && STRNCASECMP(optarg, "-", 1) == 0) {
					if (read_stdin(&buff[0], sizeof(buff), 0) == 0) {
						exit_code(0);
					}
				}
				else {
					fprintf(stderr, "error: unable to handle input file name: %s\n", optarg);
					exit_code(2);
				}
				file_b=1;
				break;
			case 'g':
				replace_str=optarg;
				break;
			case 'G':
				replace_b=1;
				break;
			case 'h':
				print_help();
				break;
			case 'H':
				hostname=optarg;
				break;
			case 'i':
				via_ins=0;
				break;
			case 'I':
				invite=1;
				break;
			case 'j':
				headers=optarg;
				break;
			case 'l':
				lport=str_to_int(optarg);
				break;
			case 'L':
				fix_crlf=0;
				break;
			case 'm':
				maxforw=str_to_int(optarg);
				break;
			case 'M':
				message=1;
				break;
			case 'n':
				numeric = 0;
				break;
			case 'N':
				exit_mode=EM_NAGIOS;
				break;
			case 'o':
				sleep_ms = 0;
				if (strlen(optarg) == 4 && STRNCASECMP(optarg, "rand", 4) == 0) {
					sleep_ms = -2;
				}
				else {
					sleep_ms = str_to_int(optarg);
				}
				break;
			case 'O':
				con_dis=str_alloc(strlen(optarg) + 1);
				strncpy(con_dis, optarg, strlen(optarg));
				break;
			case 'p':
				parse_uri(optarg, &scheme, &user, &host, &rport);
				if (host == NULL) {
					fprintf(stderr, "error: missing in host in outbound proxy\n");
					exit_code(2);
				}
				if (is_ip(host)) {
					address = getaddress(host);
					if (transport == 0)
						transport = SIP_UDP_TRANSPORT;
				}
				else {
					if (!rport) {
						address = getsrvadr(host, &rport, &tsp);
						if (tsp != 0)
							transport = tsp;
					}
					if (!address) {
						address = getaddress(host);
						if (address && verbose > 1)
							printf("using A record: %s\n", host);
					}
					if (!address){
						fprintf(stderr, "error:unable to determine the outbound proxy "
							"address\n");
						exit_code(2);
					}
				}
				outbound_proxy=1;
				break;
			case 'P':
				processes=str_to_int(optarg);
				break;
			case 'q':
				if (re) {
					/* previously allocated -- free */
					regfree(re);
				} else {
					/* never tried -- allocate */
					re=malloc(sizeof(regex_t));
				};
				if (!re) {
					fprintf(stderr, "Error: can't allocate RE\n");
					exit_code(2);
				};
				if (regcomp(re, optarg, REG_EXTENDED|REG_ICASE|REG_NEWLINE )!=0) {
					fprintf(stderr, "Error: compiling RE: %s\n", optarg );
					exit_code(2);
				};
				break;
			case 'r':
				port = 0;
				port=str_to_int(optarg);
				if (rport) {
					fprintf(stderr, "warning: you are overwritting the destination port with the r argument\n");
				}
				rport = port;
				break;
			case 'R':
				randtrash=1;
				break;
			case 's':
				parse_uri(optarg, &scheme, &user, &host, &port);
				if (scheme == NULL) {
					fprintf(stderr, "error: missing scheme in sip uri\n");
					exit_code(2);
				}
				if (strlen(optarg) == 4 && STRNCASECMP(optarg,"sips",4) == 0){
					fprintf(stderr, "error: sips is not supported yet\n");
					exit_code(2);
				}
				else if (strlen(optarg) != 3 || STRNCASECMP(optarg,"sip",3) != 0){
					fprintf(stderr, "error: scheme of sip uri has to be sip\n");
					exit_code(2);
				}
				if (user != NULL) {
					username = user;
				}
				if (host != NULL) {
					domainname = host;
				}
				else {
					fprintf(stderr, "error: missing hostname in sip uri\n");
					exit_code(2);
				}
				if (port && !rport) {
					rport = port;
				}
				if (is_ip(domainname)) {
					address = getaddress(domainname);
					if (transport == 0)
						transport = SIP_UDP_TRANSPORT;
				}
				else {
					if (!rport && !address) {
						address = getsrvadr(domainname, &rport, &tsp);
						if (tsp != 0)
							transport = tsp;
					}
					if (!address) {
						address = getaddress(domainname);
						if (address && verbose > 1)
							printf("using A record: %s\n", domainname);
					}
					if (!address){
						fprintf(stderr, "error:unable to determine the IP address for: %s\n", domainname);
						exit_code(2);
					}
				}
				if (port != 0) {
					backup = str_alloc(strlen(domainname)+1+6);
					snprintf(backup, strlen(domainname)+6, "%s:%i", domainname, port);
					domainname = backup;
				}
				uri_b=1;
				break;
			case 'S':
				fprintf(stderr, "warning: symmetric does not work with a-symmetric servers\n");
				symmetric=1;
				break;
			case 't':
				trashchar=str_to_int(optarg);
				break;
			case 'T':
				trace=1;
				break;
			case 'U':
				usrloc=1;
				break;
			case 'u':
				auth_username=str_alloc(strlen(optarg) + 1);
				strncpy(auth_username, optarg, strlen(optarg));
				break;
			case 'v':
				verbose++;
				break;
			case 'V':
				printf("sipsak %s  by Nils Ohlmeier\n Copyright (C) 2002-2004"
						" FhG Fokus\n Copyright (C) 2004-2005 Nils Ohlmeier\n", 
						SIPSAK_VERSION);
				printf(" compiled with DEFAULT_TIMEOUT=%i, FQDN_SIZE=%i",
						DEFAULT_TIMEOUT, FQDN_SIZE);
#ifdef RAW_SUPPORT
				printf(", RAW_SUPPORT");
#endif
#ifdef HAVE_GETOPT_LONG
				printf(", LONG_OPTS");
#endif
#ifdef HAVE_GNUTLS
				printf(", GNUTLS_MD5");
#else
# ifdef HAVE_FULL_OPENSSL
				printf(", OPENSSL_MD5");
# else
				printf(", INTERNAL_MD5");
# endif
#endif
#ifdef HAVE_OPENSSL_SHA1
				printf(", OPENSSL_SHA1");
#endif
#ifdef HAVE_CARES_H
				printf(", SRV_SUPPORT(ARES)");
#else
# ifdef HAVE_RULI_H
				printf(", SRV_SUPPORT(RULI)");
# endif
#endif
#ifdef HAVE_STRCASESTR
				printf(", STR_CASE_INSENSITIVE");
#endif
#ifdef HAVE_STRNCASECMP
				printf(", CMP_CASE_INSENSITIVE");
#endif
				printf("\n");
				exit_code(0);
				break;
			case 'w':
				warning_ext=1;
				break;
			case 'W':
				nagios_warn = str_to_int(optarg);
				break;
			case 'x':
				expires_t=str_to_int(optarg);
				break;
#ifdef HAVE_GETOPT_LONG
			case 'X':
				print_long_help();
				break;
#endif
			case 'z':
				rand_rem=str_to_int(optarg);
				if (rand_rem < 0 || rand_rem > 100) {
					fprintf(stderr, "error: z option must between 0 and 100\n");
					exit_code(2);
				}
				break;
			default:
				fprintf(stderr, "error: unknown parameter %c\n", c);
				exit_code(2);
				break;
		}
	}

	if (rport == 0) {
		rport =  5060;
	}
	if (rport > 65535 || rport <= 0) {
		fprintf(stderr, "error: invalid remote port: %i\n", rport);
		exit_code(2);
	}
	if (transport == 0) {
		transport = SIP_UDP_TRANSPORT;
	}

	/* replace LF with CRLF if we read from a file */
	if ((file_b) && (fix_crlf)) {
		insert_cr(buff);
	}
	if (headers) {
		backup = str_alloc(strlen(headers) + 30); // FIXME
		strcpy(backup, headers);
		headers = backup;
		replace_string(headers, "\\n", "\r\n");
		backup = headers + strlen(headers) - 1;
		if (*backup != '\n') {
			strcpy(backup + 1, "\r\n");
		}
		if (file_b)
			insert_header(buff, headers, 1);
	}
	/* lots of conditions to check */
	if (trace) {
		if (usrloc || flood || randtrash) {
			fprintf(stderr, "error: trace can't be combined with usrloc, random or "
				"flood\n");
			exit_code(2);
		}
		if (!uri_b) {
			fprintf(stderr, "error: for trace mode a SIPURI is realy needed\n");
			exit_code(2);
		}
		if (file_b) {
			fprintf(stderr, "warning: file will be ignored for tracing.");
		}
		if (!username) {
			fprintf(stderr, "error: for trace mode without a file the SIPURI have to "
				"contain a username\n");
			exit_code(2);
		}
		if (!via_ins){
			fprintf(stderr, "warning: Via-Line is needed for tracing. Ignoring -i\n");
			via_ins=1;
		}
		if (!warning_ext) {
			fprintf(stderr, "warning: IP extract from warning activated to be more "
				"informational\n");
			warning_ext=1;
		}
		if (maxforw==-1) maxforw=255;
	}
	else if (usrloc || invite || message) {
		if (trace || flood || randtrash) {
			fprintf(stderr, "error: usrloc can't be combined with trace, random or "
				"flood\n");
			exit_code(2);
		}
		if (!username || !uri_b) {
			fprintf(stderr, "error: for the USRLOC mode you have to give a SIPURI with "
				"a username\n       at least\n");
			exit_code(2);
		}
		if (namebeg>0 && nameend==-1) {
			fprintf(stderr, "error: if a starting numbers is given also an ending "
				"number have to be specified\n");
			exit_code(2);
		}
		if (invite && message) {
			fprintf(stderr, "error: invite and message tests are XOR\n");
			exit_code(2);
		}
		if (!usrloc && invite && !lport) {
			fprintf(stderr, "warning: Do NOT use the usrloc invite mode without "
				"registering sipsak before.\n         See man page for "
				"details.\n");
			exit_code(2);
		}
		if (contact_uri!=NULL) {
			if (invite || message) {
				fprintf(stderr, "error: Contact uri is not support for invites or "
					"messages\n");
				exit_code(2);
			}
			if (nameend!=-1 || namebeg!=-1) {
				fprintf(stderr, "warning: ignoring starting or ending number if Contact"
					" is given\n");
				nameend=namebeg=0;
			}
			if (rand_rem) {
				fprintf(stderr, "warning: ignoring -z option when Contact is given\n");
				rand_rem=0;
			}
		}
		if (via_ins) {
			fprintf(stderr, "warning: ignoring -i option when in usrloc mode\n");
			via_ins=0;
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else if (flood) {
		if (trace || usrloc || randtrash) {
			fprintf(stderr, "error: flood can't be combined with trace, random or "
				"usrloc\n");
			exit_code(2);
		}
		if (!uri_b) {
			fprintf(stderr, "error: we need at least a sip uri for flood\n");
			exit_code(2);
		}
		if (redirects) {
			fprintf(stderr, "warning: redirects are not expected in flood. "
				"disableing\n");
			redirects=0;
		}
	}
	else if (randtrash) {
		if (trace || usrloc || flood) {
			fprintf(stderr, "error: random can't be combined with trace, flood or "
				"usrloc\n");
			exit_code(2);
		}
		if (!uri_b) {
			fprintf(stderr, "error: need at least a sip uri for random\n");
			exit_code(2);
		}
		if (redirects) {
			fprintf(stderr, "warning: redirects are not expected in random. "
				"disableing\n");
			redirects=0;
		}
		if (verbose) {
			fprintf(stderr, "warning: random characters may destroy your terminal "
				"output\n");
		}
	}
	else if (mes_body) {
		if (!message) {
			fprintf(stderr, "warning: to send a message mode (-M) is required. activating\n");
			message=1;
		}
		if (!uri_b) {
			fprintf(stderr, "error: need at least a sip uri to send a meesage\n");
			exit_code(2);
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else {
		if (!uri_b) {
			fprintf(stderr, "error: a spi uri is needed at least\n");
			exit_code(2);
		}
	}

	switch (transport) {
		case SIP_TLS_TRANSPORT:
			transport_str = TRANSPORT_TLS_STR;
			break;
		case SIP_TCP_TRANSPORT:
			transport_str = TRANSPORT_TCP_STR;
			break;
		case SIP_UDP_TRANSPORT:
			transport_str = TRANSPORT_UDP_STR;
			break;
		default:
			fprintf(stderr, "unknown transport: %i\n", transport);
			exit_code(2);
	}

	/* determine our hostname */
	get_fqdn();
	
	/* this is not a cryptographic random number generator,
	   but hey this is only a test-tool => should be satisfying*/
	srand(time(0) ^ getpid());
	
	if (processes > 1) {
		if (signal(SIGCHLD , sigchld_handler)  == SIG_ERR ) {
			fprintf(stderr, "error: Could not install SIGCHLD handler\n");
			exit_code(2);
		}
	}

	for(i = 0; i < processes - 1; i++) {
		if ((pid = fork()) < 0) {
			fprintf(stderr, "error: Cannot fork\n");
			exit_code(2);
		}
		
		if (pid == 0){
	    	/* child */
			upp = (nameend - namebeg + 1) / processes;
			namebeg = namebeg + upp * i;
			nameend = namebeg + upp;
			shoot(&buff[0], sizeof(buff));
		} else {
			if (lport) {
				lport++;
			}
		}
		
		/* Delay execution of children so that the
		 * time of the first transmission gets spread over
		 * the retransmission interval evenly
		 */
		ts.tv_sec = 0;
		ts.tv_nsec = (float)DEFAULT_TIMEOUT / (float)processes * (float)1000 * (float)1000;
		nanosleep(&ts, 0);
	}

	/* here we go...*/
	if (processes > 1) {
		upp = (nameend - namebeg + 1) / processes;
		namebeg = namebeg + upp * i;
		nameend = namebeg + upp;
	}
	shoot(&buff[0], sizeof(buff));

	/* normaly we won't come back here, but to satisfy the compiler */
	return 0;
}
Exemple #12
0
/* because the full qualified domain name is needed by many other
   functions it will be determined by this function.
*/
void get_fqdn() {
	char hname[100], dname[100], hlp[18];
	size_t namelen=100;
	struct hostent* he;
	struct utsname un;

	memset(&hname, 0, sizeof(hname));
	memset(&dname, 0, sizeof(dname));
	memset(&hlp, 0, sizeof(hlp));

	if (hostname) {
		strncpy(fqdn, hostname, FQDN_SIZE-1);
		strncpy(hname, hostname, sizeof(hname)-1);
	}
	else {
		if ((uname(&un))==0) {
			strncpy(hname, un.nodename, sizeof(hname)-1);
		}
		else {
			if (gethostname(&hname[0], namelen) < 0) {
				fprintf(stderr, "error: cannot determine hostname\n");
				exit_code(2, __PRETTY_FUNCTION__, "failed to determine hostname");
			}
		}
#ifdef HAVE_GETDOMAINNAME
		/* a hostname with dots should be a domainname */
		if ((strchr(hname, '.'))==NULL) {
			if (getdomainname(&dname[0], namelen) < 0) {
				fprintf(stderr, "error: cannot determine domainname\n");
				exit_code(2, __PRETTY_FUNCTION__, "failed to get domainname");
			}
			if (strcmp(&dname[0],"(none)")!=0)
				snprintf(fqdn, FQDN_SIZE, "%s.%s", hname, dname);
		}
		else {
			strncpy(fqdn, hname, FQDN_SIZE-1);
		}
#endif
	}

	if (!(numeric == 1 && is_ip(fqdn))) {
		he=gethostbyname(hname);
		if (he) {
			if (numeric == 1) {
				snprintf(hlp, sizeof(hlp), "%s", inet_ntoa(*(struct in_addr *) he->h_addr_list[0]));
				strncpy(fqdn, hlp, FQDN_SIZE-1);
			}
			else {
				if ((strchr(he->h_name, '.'))!=NULL && (strchr(hname, '.'))==NULL) {
					strncpy(fqdn, he->h_name, FQDN_SIZE-1);
				}
				else {
					strncpy(fqdn, hname, FQDN_SIZE-1);
				}
			}
		}
		else {
			fprintf(stderr, "error: cannot resolve local hostname: %s\n", hname);
			exit_code(2, __PRETTY_FUNCTION__, "failed to resolve local hostname");
		}
	}
	if ((strchr(fqdn, '.'))==NULL) {
		if (hostname) {
			fprintf(stderr, "warning: %s is not resolvable... continouing anyway\n", fqdn);
			strncpy(fqdn, hostname, FQDN_SIZE-1);
		}
		else {
			fprintf(stderr, "error: this FQDN or IP is not valid: %s\n", fqdn);
			exit_code(2, __PRETTY_FUNCTION__, "invalid IP or FQDN");
		}
	}

	if (verbose > 2)
		printf("fqdnhostname: %s\n", fqdn);
}
Exemple #13
0
static const unsigned char *parse_rr(const unsigned char *aptr, const unsigned char *abuf, int alen) {
	char *name;
	long len;
	int status, type, dnsclass, dlen;
	struct in_addr addr;

	dbg("ca_tmpname: %s\n", ca_tmpname);
	status = ares_expand_name(aptr, abuf, alen, &name, &len);
	if (status != ARES_SUCCESS) {
		printf("error: failed to expand query name\n");
		exit_code(2, __PRETTY_FUNCTION__, "failed to expand query name");
	}
	aptr += len;
	if (aptr + NS_RRFIXEDSZ > abuf + alen) {
		printf("error: not enough data in DNS answer 1\n");
		free(name);
		return NULL;
	}
	type = DNS_RR_TYPE(aptr);
	dnsclass = DNS_RR_CLASS(aptr);
	dlen = DNS_RR_LEN(aptr);
	aptr += NS_RRFIXEDSZ;
	if (aptr + dlen > abuf + alen) {
		printf("error: not enough data in DNS answer 2\n");
		free(name);
		return NULL;
	}
	if (dnsclass != CARES_CLASS_C_IN) {
		printf("error: unsupported dnsclass (%i) in DNS answer\n", dnsclass);
		free(name);
		return NULL;
	}
	if (type != CARES_TYPE_SRV && type != CARES_TYPE_A && type != CARES_TYPE_CNAME) {
		printf("error: unsupported DNS response type (%i)\n", type);
		free(name);
		return NULL;
	}
	if (type == CARES_TYPE_SRV) {
		free(name);
		caport = DNS__16BIT(aptr + 4);
		dbg("caport: %i\n", caport);
		status = ares_expand_name(aptr + 6, abuf, alen, &name, &len);
		if (status != ARES_SUCCESS) {
			printf("error: failed to expand SRV name\n");
			return NULL;
		}
		dbg("SRV name: %s\n", name);
		if (is_ip(name)) {
			caadr = inet_addr(name);
			free(name);
		}
		else {
			ca_tmpname = name;
		}
	}
	else if (type == CARES_TYPE_CNAME) {
		if ((ca_tmpname != NULL) &&
				(STRNCASECMP(ca_tmpname, name, strlen(ca_tmpname)) == 0)) {
			ca_tmpname = malloc(strlen(name));
			if (ca_tmpname == NULL) {
				printf("error: failed to allocate memory\n");
				exit_code(2, __PRETTY_FUNCTION__, "memory allocation failure");
			}
			strcpy(ca_tmpname, name);
			free(name);
		}
		else {
			free(name);
			status = ares_expand_name(aptr, abuf, alen, &name, &len);
			if (status != ARES_SUCCESS) {
				printf("error: failed to expand CNAME\n");
				return NULL;
			}
			dbg("CNAME: %s\n", name);
			if (is_ip(name)) {
				caadr = inet_addr(name);
				free(name);
			}
			else {
				ca_tmpname = name;
			}
		}
	}
	else if (type == CARES_TYPE_A) {
		if (dlen == 4 && STRNCASECMP(ca_tmpname, name, strlen(ca_tmpname)) == 0) {
			memcpy(&addr, aptr, sizeof(struct in_addr));
			caadr = addr.s_addr;
		}
		free(name);
	}
	return aptr + dlen;
}
Exemple #14
0
int main(int argc, char **argv)
{
	int ret;
	int i;
	gnutls_session_t state;
	char portname[6];
	socket_st hd;
	char app_proto[32] = "";

	cmd_parser(argc, argv);

#ifndef _WIN32
	signal(SIGPIPE, SIG_IGN);
#endif

	sockets_init();

	if (gnutls_global_init() < 0) {
		fprintf(stderr, "global state initialization error\n");
		exit(1);
	}

	gnutls_global_set_log_function(tls_log_func);
	gnutls_global_set_log_level(debug);

	/* get server name */
	snprintf(portname, sizeof(portname), "%d", port);

	/* X509 stuff */
	if (gnutls_certificate_allocate_credentials(&xcred) < 0) {	/* space for 2 certificates */
		fprintf(stderr, "memory error\n");
		exit(1);
	}

	/* SRP stuff */
#ifdef ENABLE_SRP
	if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) {
		fprintf(stderr, "memory error\n");
		exit(1);
	}
#endif

#ifdef ENABLE_ANON
	/* ANON stuff */
	if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) {
		fprintf(stderr, "memory error\n");
		exit(1);
	}
#endif

	if (HAVE_OPT(STARTTLS_PROTO)) {
		snprintf(app_proto, sizeof(app_proto), "%s", OPT_ARG(STARTTLS_PROTO));
	}

	if (app_proto[0] == 0) {
		snprintf(app_proto, sizeof(app_proto), "%s", port_to_service(portname, "tcp"));
	}

	sockets_init();

	i = 0;

	printf("GnuTLS debug client %s\n", gnutls_check_version(NULL));
	printf("Checking %s:%s\n", hostname, portname);
	do {

		if (tls_tests[i].test_name == NULL)
			break;	/* finished */

		/* if neither of SSL3 and TLSv1 are supported, exit
		 */
		if (i > 6 && tls1_2_ok == 0 && tls1_1_ok == 0 && tls1_ok == 0
		    && ssl3_ok == 0) {
			fprintf(stderr,
				"\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1 and TLS 1.2\n");
			break;
		}

		socket_open(&hd, hostname, portname, 0, NULL);
		hd.verbose = verbose;

		socket_starttls(&hd, app_proto);

		gnutls_init(&state, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);

		gnutls_transport_set_ptr(state, (gnutls_transport_ptr_t)
					 gl_fd_to_handle(hd.fd));
		set_read_funcs(state);
		if (hostname && is_ip(hostname) == 0)
			gnutls_server_name_set(state, GNUTLS_NAME_DNS,
					       hostname, strlen(hostname));

		do {
			if (strcmp(app_proto, "https") != 0 && tls_tests[i].https_only != 0) {
				i++;
				break;
			}

			ret = tls_tests[i].func(state);

			if (ret != TEST_IGNORE) {
				printf("%58s...", tls_tests[i].test_name);
				fflush(stdout);
			}

			if (ret == TEST_SUCCEED) {
				if (tls_tests[i].suc_str == NULL)
					printf(" %s\n", ext_text);
				else
					printf(" %s\n", tls_tests[i].suc_str);
			} else if (ret == TEST_FAILED)
				printf(" %s\n", tls_tests[i].fail_str);
			else if (ret == TEST_UNSURE)
				printf(" %s\n", tls_tests[i].unsure_str);
			else if (ret == TEST_IGNORE) {
				if (tls_tests[i+1].test_name)
					i++;
				else
					break;
			}
		}
		while (ret == TEST_IGNORE
		       && tls_tests[i].test_name != NULL);

		gnutls_deinit(state);

		socket_bye(&hd);

		i++;
	}
	while (1);

#ifdef ENABLE_SRP
	gnutls_srp_free_client_credentials(srp_cred);
#endif
	gnutls_certificate_free_credentials(xcred);
#ifdef ENABLE_ANON
	gnutls_anon_free_client_credentials(anon_cred);
#endif
	gnutls_global_deinit();

	return 0;
}
Exemple #15
0
void dowse_output(const char *descr, iaddr from, iaddr to, uint8_t proto, int isfrag,
              unsigned sport, unsigned dport, my_bpftimeval ts,
              const u_char *pkt_copy, unsigned olen,
              const u_char *dnspkt, unsigned dnslen) {
    /* dnspkt may be NULL if IP packet does not contain a valid DNS message */

    char output[MAX_OUTPUT];

    if (dnspkt) {

        ns_msg msg;
        int qdcount;
        ns_rr rr;

        int *val;
        char *sval;

        char *extracted;
        char *resolved;
        char *from;
        int res;
        char action = 'A';

        char from_color[16];

        ns_initparse(dnspkt, dnslen, &msg);
        if (!ns_msg_getflag(msg, ns_f_qr)) return;

        /*
         * -- flags --
         * 0    1                5    6    7    8           11               15
         * +----+----------------+----+----+----+-----------+----------------+
         * | QR | Operation Code | AA | TC | RA |   Zero    |    Recode      |
         * +----+----------------+----+----+----+-----------+----------------+
         *
         * Question/Response          : ns_f_qr
         * Operation code             : ns_f_opcode
         * Authoritative Answer       : ns_f_aa
         * Truncation occurred        : ns_f_tc
         * Recursion Desired          : ns_f_rd
         * Recursion Available        : ns_f_ra
         * MBZ                        : ns_f_z
         * Authentic Data (DNSSEC)    : ns_f_ad
         * Checking Disabled (DNSSEC) : ns_f_cd
         * Response code              : ns_f_rcode
         */
        // logerr("msg: %p",msg);
        qdcount = ns_msg_count(msg, ns_s_qd);
        if (qdcount > 0 && 0 == ns_parserr(&msg, ns_s_qd, 0, &rr)) {

            // where the query comes from
            from = ia_resolv(to);

            // if its from ourselves omit it
            if(strncmp(from,hostname,MAX_DOMAIN)==0) return;
            if(own_ipv4) if(strncmp(from,own_ipv4,MAX_DOMAIN)==0) return;
            // not reverse resolved means not known by Dowse, code RED
            if(is_ip(from)) strcpy(from_color,"#FF0000");


            resolved = ns_rr_name(rr);
            // what domain is being looked up
            extracted = extract_domain(resolved);

            res = hashmap_get(visited, extracted, (void**)(&val));
            switch(res) {

                // TODO: fix malloc and strdup here as they grow as a leak on long term
            case MAP_MISSING : // never visited

                /* ==13150== 992 bytes in 248 blocks are definitely lost in loss record 45 of 49 */
                /*     ==13150==    at 0x4C28C20: malloc (vg_replace_malloc.c:296) */
                /*     ==13150==    by 0x5C3D326: dowse_output (dowse.c:417) */
                /*     ==13150==    by 0x404CAB: output (dnscap.c:2201) */
                /*     ==13150==    by 0x406779: network_pkt (dnscap.c:2164) */
                /*     ==13150==    by 0x407065: dl_pkt (dnscap.c:1608) */
                /*     ==13150==    by 0x503F5E9: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*     ==13150==    by 0x5043783: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*     ==13150==    by 0x4037E0: poll_pcaps (dnscap.c:1344) */
                /*     ==13150==    by 0x4037E0: main (dnscap.c:406) */
                val = malloc(sizeof(int));
                *val = 1; // just a placeholder for now

                /* ==13150== 3,069 bytes in 248 blocks are definitely lost in loss record 47 of 49 */
                /*       ==13150==    at 0x4C28C20: malloc (vg_replace_malloc.c:296) */
                /*       ==13150==    by 0x5511A69: strdup (strdup.c:42) */
                /*       ==13150==    by 0x5C3D34D: dowse_output (dowse.c:419) */
                /*       ==13150==    by 0x404CAB: output (dnscap.c:2201) */
                /*       ==13150==    by 0x406779: network_pkt (dnscap.c:2164) */
                /*       ==13150==    by 0x407065: dl_pkt (dnscap.c:1608) */
                /*       ==13150==    by 0x503F5E9: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*       ==13150==    by 0x5043783: ??? (in /usr/lib/x86_64-linux-gnu/libpcap.so.1.6.2) */
                /*       ==13150==    by 0x4037E0: poll_pcaps (dnscap.c:1344) */
                /*       ==13150==    by 0x4037E0: main (dnscap.c:406) */
                res = hashmap_put(visited, strdup(extracted), val);
                break;

            case MAP_OK: // already visited
                action = 'M';
                break;

                // TODO error checks
            case MAP_FULL:
            case MAP_OMEM:
                break;
            }


            // compose the path of the detected query
            // add category if listed
            if(listpath) { // add known domain list information
                res = hashmap_get(domainlist, extracted, (void**)(&sval));
                switch(res) {

                case MAP_OK:
                    /* render with the category in front of domain */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s/%s",
                             ts2epoch(&ts,NULL), // from our epoch.c
                             from, action, tld, sval, extracted);
                    break;
                default:
                    /* render only the domain in root category */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                             ts2epoch(&ts,NULL), // from our epoch.c
                             from, action, tld, extracted);
                    break;
                }
            } else
                /* render only the domain in root category */
                snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                         ts2epoch(&ts,NULL), // from our epoch.c
                         from, action, tld, extracted);



            /* write to file */
            if(fileout) {
                fputs(output, fileout);
                fputc('\n',fileout);
                if(fileout) fflush(fileout);
            }

            /* print fast on console for realtime */
            if(console) {
                puts(output);
                fflush(stdout);
            }

            if(redis) {
                rreply = redisCommand(redis, "PUBLISH dns-query-channel %s", output);
                logerr("PUBLISH dns-query-channel: %s\n", rreply->str);
                freeReplyObject(rreply);
            }

        }


    }

}
Exemple #16
0
void dowse_output(const char *descr, iaddr from, iaddr to, uint8_t proto, int isfrag,
              unsigned sport, unsigned dport, my_bpftimeval ts,
              const u_char *pkt_copy, unsigned olen,
              const u_char *dnspkt, unsigned dnslen) {
    /* dnspkt may be NULL if IP packet does not contain a valid DNS message */

    char output[MAX_OUTPUT];

    if (dnspkt) {

        ns_msg msg;
        int qdcount;
        ns_rr rr;

        int *val;
        char *sval;

        char *extracted;
        char *resolved;
        char *from;
        int res;
        char action = 'A';

        char from_color[16];

        ns_initparse(dnspkt, dnslen, &msg);
        if (!ns_msg_getflag(msg, ns_f_qr)) return;

        /*
         * -- flags --
         * 0    1                5    6    7    8           11               15
         * +----+----------------+----+----+----+-----------+----------------+
         * | QR | Operation Code | AA | TC | RA |   Zero    |    Recode      |
         * +----+----------------+----+----+----+-----------+----------------+
         *
         * Question/Response          : ns_f_qr
         * Operation code             : ns_f_opcode
         * Authoritative Answer       : ns_f_aa
         * Truncation occurred        : ns_f_tc
         * Recursion Desired          : ns_f_rd
         * Recursion Available        : ns_f_ra
         * MBZ                        : ns_f_z
         * Authentic Data (DNSSEC)    : ns_f_ad
         * Checking Disabled (DNSSEC) : ns_f_cd
         * Response code              : ns_f_rcode
         */
        // logerr("msg: %p",msg);
        qdcount = ns_msg_count(msg, ns_s_qd);
        if (qdcount > 0 && 0 == ns_parserr(&msg, ns_s_qd, 0, &rr)) {

            // where the query comes from
            from = ia_resolv(to);

            // if its from ourselves omit it
            if(strncmp(from,hostname,MAX_DOMAIN)==0) return;
            if(own_ipv4) if(strncmp(from,own_ipv4,MAX_DOMAIN)==0) return;
            // not reverse resolved means not known by Dowse, code RED
            if(is_ip(from)) strcpy(from_color,"#FF0000");


            resolved = ns_rr_name(rr);
            // what domain is being looked up
            extracted = extract_domain(resolved);

            res = hashmap_get(visited, extracted, (void**)(&val));
            switch(res) {

            case MAP_MISSING : // never visited
                val = malloc(sizeof(int));
                *val = 1; // just a placeholder for now
                res = hashmap_put(visited, strdup(extracted), val);
                break;

            case MAP_OK: // already visited
                action = 'M';
                break;

                // TODO error checks
            case MAP_FULL:
            case MAP_OMEM:
                break;
            }


            // compose the path of the detected query
            // add category if listed
            if(listpath) { // add known domain list information
                res = hashmap_get(domainlist, extracted, (void**)(&sval));
                switch(res) {

                case MAP_OK:
                    /* render with the category in front of domain */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s/%s",
                             ts.tv_sec, from, action, tld, sval, extracted);
                    break;
                default:
                    /* render only the domain in root category */
                    snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                             ts.tv_sec, from, action, tld, extracted);
                    break;
                }
            } else
                /* render only the domain in root category */
                snprintf(output,MAX_OUTPUT,"%lu|%s|%c|%s/%s",
                         ts.tv_sec, from, action, tld, extracted);



            /* write to file */
            if(fileout) {
                fputs(output, fileout);
                fputc('\n',fileout);
                if(fileout) fflush(fileout);
            }

            /* print fast on console for realtime */
            if(console) {
                puts(output);
                fflush(stdout);
            }

        }


    }

}
Exemple #17
0
static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
{
    access_dir_conf *d = (access_dir_conf *) dv;
    allowdeny *a;
    char *s;

    if (strcasecmp(from, "from"))
	return "allow and deny must be followed by 'from'";

    a = (allowdeny *) ap_push_array(cmd->info ? d->allows : d->denys);
    a->x.from = where;
    a->limited = cmd->limited;

    if (!strncasecmp(where, "env=", 4)) {
	a->type = T_ENV;
	a->x.from += 4;

    }
    else if (!strcasecmp(where, "all")) {
	a->type = T_ALL;

    }
    else if ((s = strchr(where, '/'))) {
	struct in_addr mask;

	a->type = T_IP;
	/* trample on where, we won't be using it any more */
	*s++ = '\0';

	if (!is_ip(where)
	    || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
	    a->type = T_FAIL;
	    return "syntax error in network portion of network/netmask";
	}

	/* is_ip just tests if it matches [\d.]+ */
	if (!is_ip(s)) {
	    a->type = T_FAIL;
	    return "syntax error in mask portion of network/netmask";
	}
	/* is it in /a.b.c.d form? */
	if (strchr(s, '.')) {
	    mask.s_addr = ap_inet_addr(s);
	    if (mask.s_addr == INADDR_NONE) {
		a->type = T_FAIL;
		return "syntax error in mask portion of network/netmask";
	    }
	}
	else {
	    int i;

	    /* assume it's in /nnn form */
	    i = atoi(s);
	    if (i > 32 || i <= 0) {
		a->type = T_FAIL;
		return "invalid mask in network/netmask";
	    }
	    mask.s_addr = 0xFFFFFFFFUL << (32 - i);
	    mask.s_addr = htonl(mask.s_addr);
	}
	a->x.ip.mask = mask;
        a->x.ip.net.s_addr  = (a->x.ip.net.s_addr & mask.s_addr);   /* pjr - This fixes PR 4770 */
    }
    else if (ap_isdigit(*where) && is_ip(where)) {
	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
	int shift;
	char *t;
	int octet;

	a->type = T_IP;
	/* parse components */
	s = where;
	a->x.ip.net.s_addr = 0;
	a->x.ip.mask.s_addr = 0;
	shift = 24;
	while (*s) {
	    t = s;
	    if (!ap_isdigit(*t)) {
		a->type = T_FAIL;
		return "invalid ip address";
	    }
	    while (ap_isdigit(*t)) {
		++t;
	    }
	    if (*t == '.') {
		*t++ = 0;
	    }
	    else if (*t) {
		a->type = T_FAIL;
		return "invalid ip address";
	    }
	    if (shift < 0) {
		a->type = T_FAIL;
		return "invalid ip address, only 4 octets allowed";
	    }
	    octet = atoi(s);
	    if (octet < 0 || octet > 255) {
		a->type = T_FAIL;
		return "each octet must be between 0 and 255 inclusive";
	    }
	    a->x.ip.net.s_addr |= (unsigned int)octet << shift;
	    a->x.ip.mask.s_addr |= 0xFFUL << shift;
	    s = t;
	    shift -= 8;
	}
	a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
	a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
    }
    else {
	a->type = T_HOST;
    }

    return NULL;
}
Exemple #18
0
static bool
pred_is_ip(arguments_t args, SkBuff b)
{
        return  is_ip(b);
}
Exemple #19
0
int set_range(char* range_str, struct ip_range* range_struct) {
  if(is_ip(range_str, range_struct)) return 1;
  if(is_range1(range_str, range_struct)) return 1;
  if(is_range2(range_str, range_struct)) return 1;
  return 0;
};
/* Resolves server name to ip address.
 * input:
 * 	unc - server UNC
 * output:
 * 	*ip_addr - pointer to server ip, caller responcible for freeing it.
 * return 0 on success
 */
int
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
{
	const struct cred *saved_cred;
	int rc = -EAGAIN;
	struct key *rkey = ERR_PTR(-EAGAIN);
	char *name;
	char *data = NULL;
	int len;

	if (!ip_addr || !unc)
		return -EINVAL;

	/* search for server name delimiter */
	len = strlen(unc);
	if (len < 3) {
		cFYI(1, ("%s: unc is too short: %s", __func__, unc));
		return -EINVAL;
	}
	len -= 2;
	name = memchr(unc+2, '\\', len);
	if (!name) {
		cFYI(1, ("%s: probably server name is whole unc: %s",
					__func__, unc));
	} else {
		len = (name - unc) - 2/* leading // */;
	}

	name = kmalloc(len+1, GFP_KERNEL);
	if (!name) {
		rc = -ENOMEM;
		return rc;
	}
	memcpy(name, unc+2, len);
	name[len] = 0;

	if (is_ip(name)) {
		cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
					__func__, name));
		data = name;
		goto skip_upcall;
	}

	saved_cred = override_creds(dns_resolver_cache);
	rkey = request_key(&key_type_dns_resolver, name, "");
	revert_creds(saved_cred);
	if (!IS_ERR(rkey)) {
		if (!(rkey->perm & KEY_USR_VIEW)) {
			down_read(&rkey->sem);
			rkey->perm |= KEY_USR_VIEW;
			up_read(&rkey->sem);
		}
		len = rkey->type_data.x[0];
		data = rkey->payload.data;
	} else {
		cERROR(1, ("%s: unable to resolve: %s", __func__, name));
		goto out;
	}

skip_upcall:
	if (data) {
		*ip_addr = kmalloc(len + 1, GFP_KERNEL);
		if (*ip_addr) {
			memcpy(*ip_addr, data, len + 1);
			if (!IS_ERR(rkey))
				cFYI(1, ("%s: resolved: %s to %s", __func__,
							name,
							*ip_addr
					));
			rc = 0;
		} else {
			rc = -ENOMEM;
		}
		if (!IS_ERR(rkey))
			key_put(rkey);
	}

out:
	kfree(name);
	return rc;
}
Exemple #21
0
int getaddress(char *host, int rport, int transport, struct addrinfo *ret) {
	struct addrinfo *result;
	struct addrinfo *res;
	int error;

	struct addrinfo hints = {
		.ai_family = AF_UNSPEC,
		.ai_socktype = transport == SIP_TCP_TRANSPORT ? SOCK_STREAM : SOCK_DGRAM
	};

	if (rport) {
		char strport[INT_DIGITS10];
		snprintf(strport, INT_DIGITS10, "%i", rport);
		error = getaddrinfo(host, strport, &hints, &result);
	} else {
		error = getaddrinfo(host, "sip", &hints, &result);
	}

	/* resolve the domain name into a list of addresses */
	if (error != 0) {
		if (error == EAI_SYSTEM) {
			perror("getaddrinfo");
		} else {
			fprintf(stderr, "error in getaddrinfo for %s: %s\n", host, gai_strerror(error));
		}
		return -1;
	}

	/* loop over all returned results and do inverse lookup */
	for (res = result; res != NULL; res = res->ai_next) {
		char hostname[NI_MAXHOST];

		error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0);
		if (error != 0) {
			fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
			continue;
		} if (*hostname != '\0') {
			memset(ret, 0, sizeof(struct addrinfo));
			memcpy(ret, res, sizeof(struct addrinfo));

			ret->ai_addr = malloc(res->ai_addrlen);
			memcpy(ret->ai_addr, res->ai_addr, res->ai_addrlen);
			break;
		}
	}

	freeaddrinfo(result);
	return 0;
}

#ifdef HAVE_CARES_H
static const unsigned char *parse_rr(const unsigned char *aptr, const unsigned char *abuf, int alen) {
	char *name;
	long len;
	int status, type, dnsclass, dlen;
	struct in_addr addr;

	dbg("ca_tmpname: %s\n", ca_tmpname);
	status = ares_expand_name(aptr, abuf, alen, &name, &len);
	if (status != ARES_SUCCESS) {
		printf("error: failed to expand query name\n");
		exit_code(2, __PRETTY_FUNCTION__, "failed to expand query name");
	}
	aptr += len;
	if (aptr + NS_RRFIXEDSZ > abuf + alen) {
		printf("error: not enough data in DNS answer 1\n");
		free(name);
		return NULL;
	}
	type = DNS_RR_TYPE(aptr);
	dnsclass = DNS_RR_CLASS(aptr);
	dlen = DNS_RR_LEN(aptr);
	aptr += NS_RRFIXEDSZ;
	if (aptr + dlen > abuf + alen) {
		printf("error: not enough data in DNS answer 2\n");
		free(name);
		return NULL;
	}
	if (dnsclass != CARES_CLASS_C_IN) {
		printf("error: unsupported dnsclass (%i) in DNS answer\n", dnsclass);
		free(name);
		return NULL;
	}
	if ((ca_tmpname == NULL && type != CARES_TYPE_SRV) ||
		(ca_tmpname != NULL &&
		 	(type != CARES_TYPE_A && type != CARES_TYPE_CNAME))) {
		printf("error: unsupported DNS response type (%i)\n", type);
		free(name);
		return NULL;
	}
	if (type == CARES_TYPE_SRV) {
		free(name);
		caport = DNS__16BIT(aptr + 4);
		dbg("caport: %i\n", caport);
		status = ares_expand_name(aptr + 6, abuf, alen, &name, &len);
		if (status != ARES_SUCCESS) {
			printf("error: failed to expand SRV name\n");
			return NULL;
		}
		dbg("SRV name: %s\n", name);
		if (is_ip(name)) {
			caadr = inet_addr(name);
			free(name);
		}
		else {
			ca_tmpname = name;
		}
	}
	else if (type == CARES_TYPE_CNAME) {
		if ((ca_tmpname != NULL) &&
				(STRNCASECMP(ca_tmpname, name, strlen(ca_tmpname)) == 0)) {
			ca_tmpname = malloc(strlen(name));
			if (ca_tmpname == NULL) {
				printf("error: failed to allocate memory\n");
				exit_code(2, __PRETTY_FUNCTION__, "memory allocation failure");
			}
			strcpy(ca_tmpname, name);
			free(name);
		}
		else {
			free(name);
			status = ares_expand_name(aptr, abuf, alen, &name, &len);
			if (status != ARES_SUCCESS) {
				printf("error: failed to expand CNAME\n");
				return NULL;
			}
			dbg("CNAME: %s\n", name);
			if (is_ip(name)) {
				caadr = inet_addr(name);
				free(name);
			}
			else {
				ca_tmpname = name;
			}
		}
	}
	else if (type == CARES_TYPE_A) {
		if (dlen == 4 && STRNCASECMP(ca_tmpname, name, strlen(ca_tmpname)) == 0) {
			memcpy(&addr, aptr, sizeof(struct in_addr));
			caadr = addr.s_addr;
		}
		free(name);
	}
	return aptr + dlen;
}