示例#1
0
文件: portmap.c 项目: proot-me/PRoot
static int handle_sysenter_end(Tracee *tracee, Config *config)
{
	int status;
	int sysnum;

	sysnum = get_sysnum(tracee, CURRENT);

	switch(sysnum) {
#define SYSARG_ADDR(n) (args_addr + ((n) - 1) * sizeof_word(tracee))

#define PEEK_WORD(addr, forced_errno)		\
	peek_word(tracee, addr);		\
	if (errno != 0) {			\
		status = forced_errno ?: -errno; \
		break;				\
	}

#define POKE_WORD(addr, value)			\
	poke_word(tracee, addr, value);		\
	if (errno != 0) {			\
		status = -errno;		\
		break;				\
	}
	
	case PR_socketcall:	{
		word_t sockfd;
		word_t args_addr;
		word_t sock_addr_saved;
		word_t sock_addr;
		word_t size;
		word_t call;
		int is_bind_syscall = sysnum == PR_bind;
		
		call = peek_reg(tracee, CURRENT, SYSARG_1);
		is_bind_syscall = call == SYS_BIND;
		args_addr = peek_reg(tracee, CURRENT, SYSARG_2);
	
		switch(call) {
		case SYS_BIND:
		case SYS_CONNECT: {
			/* Remember: PEEK_WORD puts -errno in status and breaks if an
			 * error occured.  */
			sockfd = PEEK_WORD(SYSARG_ADDR(1), 0);
			sock_addr = PEEK_WORD(SYSARG_ADDR(2), 0);
			size      = PEEK_WORD(SYSARG_ADDR(3), 0);

			sock_addr_saved = sock_addr;
			status = translate_port(tracee, config, sockfd, &sock_addr, size, is_bind_syscall);
			if (status < 0)
				break;

			/* These parameters are used/restored at the exit stage.  */
			poke_reg(tracee, SYSARG_5, sock_addr_saved);
			poke_reg(tracee, SYSARG_6, size);

			/* Remember: POKE_WORD puts -errno in status and breaks if an
			 * error occured.  */
			POKE_WORD(SYSARG_ADDR(2), sock_addr);
			POKE_WORD(SYSARG_ADDR(3), sizeof(struct sockaddr_un));
			return 0;
		}
		case SYS_LISTEN: {
			word_t sockfd;
		
			if(!config->netcoop_mode || !config->need_to_check_new_port)
				return 0;

			/* we retrieve this one from the listen() system call */
			sockfd = PEEK_WORD(SYSARG_ADDR(1), 0);
	
			status = prepare_getsockname_chained_syscall(tracee, config, sockfd, true);
			
			return status;
		}
		default:
			return 0;
		}
		break;
	}
	
#undef SYSARG_ADDR
#undef PEEK_WORD
#undef POKE_WORD

	case PR_connect:
	case PR_bind: {
		int size;
		int is_bind_syscall;
		word_t sockfd, sock_addr;

		/* 
		* Get the reg address of the socket, and the size of the structure.
		* Note that the sockaddr and addrlen are at the same position for all 4 of these syscalls.
		*/
		sockfd = peek_reg(tracee, CURRENT, SYSARG_1);
		sock_addr = peek_reg(tracee, CURRENT, SYSARG_2);
		size = (int) peek_reg(tracee, CURRENT, SYSARG_3);
		is_bind_syscall = sysnum == PR_bind;

		status = translate_port(tracee, config, sockfd, &sock_addr, size, is_bind_syscall);
		if (status < 0) {
			return status;
		}

		/* then we modify the syscall argument so that it uses the modified socket address */
		poke_reg(tracee, SYSARG_2, sock_addr);
		//poke_reg(tracee, SYSARG_3, size);
		poke_reg(tracee, SYSARG_3, sizeof(struct sockaddr_un));

		return 0;
	}
	case PR_listen: {
		word_t sockfd;
		
		if(!config->netcoop_mode || !config->need_to_check_new_port)
			return 0;

		/* we retrieve this one from the listen() system call */
		sockfd = peek_reg(tracee, CURRENT, SYSARG_1);
			
		status = prepare_getsockname_chained_syscall(tracee, config, sockfd, false);
		return status;
	}
	default:
		return 0;
	}
	
	return 0;
}
示例#2
0
static int CheckValid()
{
	char temp_arr[1024];
	char *temp_strs[1024];
    int i, l, len_strs;
	char *port_strs[1024];
	char port_range[1024];
	char mybuf[] = "00:00:00:00:00:00";

	if (strlen(sysconfig.if_in) < 1 || strlen(sysconfig.if_out) < 1)
	{
        OD("missing ifnames");
		return -1;
	}

	if (sysconfig.is_test)
	{
		if (strlen(sysconfig.src_mac.name) < 1)
		{
			/* retrieve source mac address. */
			if (source_hwaddr(sysconfig.if_out, mybuf) == -1) {
                OD("Unable to retrieve source mac");
				return -1;
				// continue, fail later
			}
			strcpy(sysconfig.src_mac.name, mybuf);
		}
		/* extract address ranges */
		extract_ip_range(&sysconfig.src_ip);
		extract_mac_range(&sysconfig.src_mac);

        for (i = 0; i < sysconfig.dst_count && i < FIO_MAX_DST_TEST; i++)
        {
            extract_ip_range(&sysconfig.dst_ip[i]);
            extract_mac_range(&sysconfig.dst_mac[i]);
        }
	}

	if (source_hwaddr(sysconfig.if_in, mybuf) == -1) {
        OD("Unable to retrieve source mac %s", sysconfig.if_in);
		return -1;
	}
	bcopy(ether_aton(mybuf), &sysconfig.if_macs[0], ETH_ALEN);
    OD("if %s mac %s", sysconfig.if_in, mybuf);
	if (source_hwaddr(sysconfig.if_out, mybuf) == -1) {
        OD("Unable to retrieve source mac %s", sysconfig.if_out);
		return -1;
	}
	bcopy(ether_aton(mybuf), &sysconfig.if_macs[1], ETH_ALEN);
    OD("if %s mac %s", sysconfig.if_out, mybuf);

    extract_mac_range(&sysconfig.defgw_mac);
    OD("defgw mac %s", sysconfig.defgw_mac.name);

	if (get_if_ip(sysconfig.if_in, &sysconfig.if_ips[0]))
        OD("<error> %s get ip", sysconfig.if_in);
	if (get_if_ip(sysconfig.if_out, &sysconfig.if_ips[1]))
        OD("<error> %s get ip", sysconfig.if_out);

    OD("read %d ipmac", g_mac_num);

	len_strs = splite_str(sysconfig.str_interested_proto, 
			sizeof(sysconfig.str_interested_proto), temp_arr, 
			1024, temp_strs, 1024, ' ');
	translate_proto(temp_strs, len_strs, 1);

	len_strs = splite_str(sysconfig.str_def_proto, 
			sizeof(sysconfig.str_def_proto), temp_arr, 
			1024, temp_strs, 1024, ' ');
	translate_proto(temp_strs, len_strs, 2);

	len_strs = splite_str(sysconfig.str_interested_port, 
			sizeof(sysconfig.str_interested_port), temp_arr, 
			1024, temp_strs, 1024, ' ');

    for (i = 0; i < len_strs; i++)
    {
        l = splite_str(temp_strs[i], strlen(temp_strs[i])+1, 
                port_range, 1024, port_strs, 1024, '~');
        translate_port(port_strs, l, i);
    }
    sysconfig.mac_lifetime *= 1000000;
    sysconfig.mac_buddy_lifetime *= 1000000;
    //sysconfig.multip_checktime *= 1000000;

    if (strlen(sysconfig.if_in))
        strncpy(sysconfig.nic_names[sysconfig.num_nic++], sysconfig.if_in, FIO_MAX_NAME_LEN);
    if (strlen(sysconfig.if_out) && strcmp(sysconfig.if_out, sysconfig.if_in))
        strncpy(sysconfig.nic_names[sysconfig.num_nic++], sysconfig.if_out, FIO_MAX_NAME_LEN);

	return 0;
}