⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdifw_svc.c

📁 开源的防火墙代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	
	return inet_addr(addr);
}

// GetLongPathName is in Windows 2000 only so make it for NT4
void	my_GetLongPathName(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWORD cchBuffer)
{
	LPSTR p_l;
	LPCSTR p_s;
	
	lpszLongPath[0] = lpszShortPath[0];
	lpszLongPath[1] = lpszShortPath[1];
	lpszLongPath[2] = lpszShortPath[2];
	lpszLongPath[3] = '\0';
	
	p_l = &lpszLongPath[3];
	p_s = &lpszShortPath[3];
	
	for (;;){
		LPSTR p_s2;
		HANDLE search;
		WIN32_FIND_DATA ffd;
		size_t len;
		BOOL overflow;
		
		p_s2 = strchr(p_s, '\\');
		
		if (p_s2 != NULL)
			len = p_s2 - p_s;
		else
			len = strlen(p_s);
		
		// check the buffer
		if (len + (p_l - lpszLongPath) >= cchBuffer)
			{
			// buffer overflow: copy and exit
			len = cchBuffer - (p_l - lpszLongPath) - 1;
			overflow = TRUE;
			}
		else
			overflow = FALSE;
		
		memcpy(p_l, p_s, len);
		p_l[len] = '\0';
		
		if (overflow)
			break;
		
		search = FindFirstFile(lpszLongPath, &ffd);
		if (search != INVALID_HANDLE_VALUE)
			{
			
			len = strlen(ffd.cFileName);
			if (p_s2 != NULL)
				len++;
			
			// check the buffer
			if (len + (p_l - lpszLongPath) >= cchBuffer)
				{
				// buffer overflow: copy and exit
				len = cchBuffer - (p_l - lpszLongPath) - 1;
				p_s2 = NULL;
				}
			
			memcpy(p_l, ffd.cFileName, len);
			
			if (p_s2 != NULL)
				{
				p_l[len - 1] = '\\';
				p_l[len] = '\0';
				}
			else
				p_l[len] = '\0';
			
			FindClose(search);
			}
		
		if (p_s2 == NULL)
			break;
		
		p_l += strlen(p_l);
		p_s = p_s2 + 1;
		}
	
	// ignore status
}

// dynamically try to link with psapi.lib
void	link_psapi(void)
{
	g_psapi = LoadLibrary("psapi.dll");
	if (g_psapi == NULL)
		{
		// no psapi.dll - log it!
		error("INIT\tCan't load psapi.dll!");
		return;
		}
	
	pEnumProcesses = (EnumProcesses_t *)GetProcAddress(g_psapi, "EnumProcesses");
	pEnumProcessModules = (EnumProcessModules_t *)GetProcAddress(g_psapi, "EnumProcessModules");
#ifdef UNICODE
	pGetModuleFileNameEx = (GetModuleFileNameEx_t *)GetProcAddress(g_psapi, "GetModuleFileNameExW");
#else
	pGetModuleFileNameEx = (GetModuleFileNameEx_t *)GetProcAddress(g_psapi, "GetModuleFileNameExA");
#endif
	
	if (pEnumProcesses == NULL || pEnumProcessModules == NULL || pGetModuleFileNameEx == NULL)
		{
		// invalid psapi.dll?
		error("INIT\tInvalid psapi.dll!");
		
		FreeLibrary(g_psapi);
		g_psapi = NULL;
		}
}

#define PRINT_IP_ADDR(addr) \
		((UCHAR *)&(addr))[0], ((UCHAR *)&(addr))[1], ((UCHAR *)&(addr))[2], ((UCHAR *)&(addr))[3]

// enum listening objects
void	enum_listen(void)
{
	ULONG size;
	struct listen_nfo *ln = NULL;
	int i, n;
	
	// try to dynamically link psapi.dll
	link_psapi();
	
	/* connect with driver */
	
	g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
			      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (g_device == INVALID_HANDLE_VALUE)
		{
		winerr(g_nfo_device_name);
		goto done;
		}
	
	/* get list of listening objects */
	
	size = sizeof(*ln) * 0x10000 * 3;	// this size is good enough :-)
	ln = (struct listen_nfo *)malloc(size);
	if (ln == NULL)
		{
		perror("malloc");
		goto done;
		}
	
	if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_LISTEN, NULL, 0,
		ln, size, &size, NULL))
		{
		winerr("DeviceIoControl");
		goto done;
		}
	
	n = size / sizeof(*ln);
	
	// sort this list!
	qsort(ln, n, sizeof(*ln), compare_ln);
	
	printf("IPProto\tAddress:Port\tProcess (pid)\n");
	printf("-------\t------------\t---------------------------------------------\n");
	
	for (i = 0; i < n ; i++)
		{
		char *proto, pname[MAX_PATH];
		
		if (ln[i].ipproto == IPPROTO_TCP)
			proto = "TCP";
		else if (ln[i].ipproto == IPPROTO_UDP)
			proto = "UDP";
		else if (ln[i].ipproto == IPPROTO_IP)
			proto = "RawIP";
		else
			proto = "?";
		
		// resolve pid!
		if (!get_pname_by_pid(ln[i].pid, pname, sizeof(pname)))
			pname[0] = '\0';
		
		printf("%s\t%d.%d.%d.%d:%d\t%s (%d)\n",
		       proto, PRINT_IP_ADDR(ln[i].addr), ntohs(ln[i].port), pname, ln[i].pid);
		}
	
	done:
	free(ln);
	if (g_device != INVALID_HANDLE_VALUE)
		CloseHandle(g_device);
}

int	compare_ln(const void *arg1, const void *arg2)
{
	const struct listen_nfo *l1 = (const struct listen_nfo *)arg1;
	const struct listen_nfo *l2 = (const struct listen_nfo *)arg2;
	int result;
	
	result = l1->ipproto - l2->ipproto;
	if (result == 0)
		{
		result = ntohl(l2->addr) - ntohl(l1->addr);
		if (result == 0)
			result = ntohs(l1->port) - ntohs(l2->port);
		}
	return result;
}

// enum connections
void	enum_connect(void)
{
	ULONG size;
	struct tcp_conn_nfo *tn = NULL;
	int i, n;
	unsigned __int64 traffic[TRAFFIC_MAX];
	
	// try to dynamically link psapi.dll
	link_psapi();
	
	/* connect with driver */
	
	g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
			      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (g_device == INVALID_HANDLE_VALUE)
		{
		winerr(g_nfo_device_name);
		goto done;
		}
	
	/* get list of listening objects */
	
	size = sizeof(*tn) * 0x10000 * 3;	// this size is good enough :-)
	tn = (struct tcp_conn_nfo *)malloc(size);
	if (tn == NULL)
		{
		perror("malloc");
		goto done;
		}
	
	if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_TCP_CONN, NULL, 0,
		tn, size, &size, NULL))
		{
		winerr("DeviceIoControl");
		goto done;
		}
	
	n = size / sizeof(*tn);
	
	// sort this list!
	qsort(tn, n, sizeof(*tn), compare_tn);
	
	for (i = 0; i < n ; i++)
		{
		char pname[MAX_PATH];
		
		if (tn[i].state >= TCP_STATE_MAX)
			tn[i].state = 0;
		
		// resolve pid!
		if (!get_pname_by_pid(tn[i].pid, pname, sizeof(pname)))
			pname[0] = '\0';
		
		printf("%s\t%d.%d.%d.%d:%d\t%d.%d.%d.%d:%d\t%s (%d)\t%u/%u\n",
		       g_tcp_states[tn[i].state],
		       PRINT_IP_ADDR(tn[i].laddr), ntohs(tn[i].lport),
		       PRINT_IP_ADDR(tn[i].raddr), ntohs(tn[i].rport),
		       pname, tn[i].pid,
		       tn[i].bytes_out, tn[i].bytes_in);
		}
	
	// output traffic counters
	get_traffic_stats(traffic);
	
	printf(
		 "\n"
		 "Traffic counters (out/in):\n"
		 "    Total:   %I64u/%I64u\n"
		 "    Counted: %I64u/%I64u\n",
		 traffic[TRAFFIC_TOTAL_OUT], traffic[TRAFFIC_TOTAL_IN],
		 traffic[TRAFFIC_COUNTED_OUT], traffic[TRAFFIC_COUNTED_IN]);
	
	done:
	free(tn);
	if (g_device != INVALID_HANDLE_VALUE)
		CloseHandle(g_device);
}

int	compare_tn(const void *arg1, const void *arg2)
{
	const struct tcp_conn_nfo *t1 = (const struct tcp_conn_nfo *)arg1;
	const struct tcp_conn_nfo *t2 = (const struct tcp_conn_nfo *)arg2;
	int result;
	
	result = t1->state - t2->state;
	if (result == 0)
		{
		result = ntohl(t1->laddr) - ntohl(t2->laddr);
		if (result == 0)
			{
			result = ntohs(t1->lport) - ntohs(t2->lport);
			if (result == 0)
				{
				result = ntohl(t1->raddr) - ntohl(t2->raddr);
				if (result == 0)
					result = ntohs(t1->rport) - ntohs(t2->rport);
				}
			}
		}
	
	return result;
}

/*
* Routing functions help us to get local IP address of outgoing datagrams or connections
* Warning! This functions are slow!
* TODO: make it faster!
*/

ULONG	get_if_ip(ULONG remote_ip)
{
	ULONG if_index;
	
	// get interface index by routing table
	if_index = route_ip(remote_ip);
	if (if_index == (ULONG)-1)
		return 0;
	
	return get_if_index_ip(if_index);
}

ULONG	route_ip(ULONG remote_ip)
{
	ULONG size, i, bestmetric, result;
	MIB_IPFORWARDTABLE *buf;
	
	// get route table
	
	size = 0;
	if (GetIpForwardTable(NULL, &size, FALSE) != ERROR_INSUFFICIENT_BUFFER)
		return (ULONG)-1;
	
	buf = (MIB_IPFORWARDTABLE *)malloc(size);
	if (buf == NULL)
		return (ULONG)-1;
	
	if (GetIpForwardTable(buf, &size, FALSE) != NO_ERROR)
		{
		free(buf);
		return (ULONG)-1;
		}
	
	// find optimal route
	
	bestmetric = (ULONG)-1;
	result = (ULONG)-1;
	
	for (i = 0; i < buf->dwNumEntries; i++)
		{
		if ((remote_ip & buf->table[i].dwForwardMask) ==
			(buf->table[i].dwForwardDest & buf->table[i].dwForwardMask))
			{
			
			if (bestmetric == (ULONG)-1 || buf->table[i].dwForwardMetric1 > bestmetric)
				{
				bestmetric = buf->table[i].dwForwardMetric1;
				result = buf->table[i].dwForwardIfIndex;
				}
			
			}
		}
	
	free(buf);
	return result;
}

ULONG	get_if_index_ip(ULONG if_index)
{
	ULONG size, i;
	MIB_IPADDRTABLE *buf;
	ULONG result;
	
	size = 0;
	if (GetIpAddrTable(NULL, &size, FALSE) != ERROR_INSUFFICIENT_BUFFER)
		return (ULONG)-1;
	
	buf = (MIB_IPADDRTABLE *)malloc(size);
	if (buf == NULL)
		return (ULONG)-1;
	
	if (GetIpAddrTable(buf, &size, FALSE) != NO_ERROR)
		{
		free(buf);
		return (ULONG)-1;
		}
	
	result = 0;
	for (i = 0; i < buf->dwNumEntries; i++)
		if (buf->table[i].dwIndex == if_index)
			{
			result = buf->table[i].dwAddr;
			break;
			}
	
	free(buf);
	return result;
}

BOOL	load_users(const char *config)
{
	BOOL result = FALSE;
	char *section, *p, *all_sids = NULL;
	int line, sid_id;
	ULONG all_sids_len = 0, all_sids_size = 0, n;
	
	section = (char *)malloc(MAX_SECTION_SIZE);
	if (section == NULL)
		{
		liberr("malloc");
		return FALSE;
		}
	GetPrivateProfileSection("_users_", section, MAX_SECTION_SIZE, config);
	
	// get lines
	sid_id = 0;
	for (p = section, line = 1; *p != '\0'; p += strlen(p) + 1, line++)
		{
		char *p2, *p3, *authority, *principal, domain[100];
		char *sid_buf;
		DWORD sid_size, domain_size;
		SID_NAME_USE use;
		
		if (*p == ';')
		continue;		// comment
		
		p2 = strchr(p, '=');
		if (p2 == NULL)
			{
			error("%s:[_users_]:%d: invalid line format (no '=' character)", config, line);
			continue;
			}
		
		*p2 = '\0';		// temporary kill '='
		
		if (sid_id != 0)
			{
			// not _default_
			p3 = strchr(p, '\\');
			if (p3 != NULL)
				{
				*p3 = '\0';
				
				authority = p;
				if (strcmp(authority, "NT AUTHORITY") == 0)
					authority = NULL;
				
				principal = p3 + 1;
				
				}
			else	{
				authority = NULL;
				principal = p;
				}
			
			// try to get SID size
			sid_size = 0;
			domain_size = 0;
			
			LookupAccountName(authority, principal, NULL, &sid_size, NULL, &domain_size, &use);
			}
		else
			sid_size = 0;		// empty SID for default
		
		if (all_sids_len + sid_size + sizeof(ULONG) >= all_sids_size)
			{
			all_sids_size += sid_size + sizeof(ULONG) + 4096;
			all_sids = (char *)realloc(all_sids, all_sids_size);
			if (all_sids == NULL)
				{
				liberr("malloc");
				goto done;
				}
			}
		sid_buf = all_sids + all_sids_len;
		all_sids_len += sid_size + sizeof(ULONG);
		
		*(ULONG *)sid_buf = sid_size;
		
		if (sid_id != 0)
			{
			domain_size = sizeof(domain);
			
			if (!LookupAccountName(authority, principal,
				(PSID)(sid_buf + sizeof(ULONG)), &sid_size, domain, &domain_size, &use))
				{
				winerr("LookupAccountName");
				error("%s:[_users_]:%d: Error getting SID for %s\\%s", config, line,
				      (authority != NULL ? authority : "."), principal);
				goto done;
				}
			if (use != SidTypeUser && use != SidTypeWellKnownGroup)
				{
				error("%s:[_users_]:%d: Invalid SID type (%d) for %s\\%s", config, line, use,
				      (authority != NULL ? authority : "."), principal);
				goto done;
				}
			
			if (p3 != NULL)
				*p3 = '\\';
				}
			
			*p2 = '=';		// recover '=' to make strlen(p) works right
		sid_id++;
		}
	
	// send all_sids buffer to filter driver!
	result = DeviceIoControl(g_device, IOCTL_CMD_SET_SIDS, all_sids, all_sids_len,
				 NULL, 0, &n, NULL);
	if (!result)
		winerr("DeviceIoControl");
	
	done:
	free(all_sids);
	free(section);
	return result;
}

void	get_sid_mask(const char *config, const char *name, UCHAR *sid_mask)
{
	BOOL result = FALSE;
	char *section, *p;
	int line, sid_id;
	
	memset(sid_mask, 0, MAX_SIDS_COUNT / 8);
	
	section = (char *)malloc(MAX_SECTION_SIZE);
	if (section == NULL)
		{
		liberr("malloc");
		return;
		}
	GetPrivateProfileSection("_users_", section, MAX_SECTION_SIZE, config);
	
	// get lines
	sid_id = 0;
	for (p = section, line = 1; *p != '\0'; p += strlen(p) + 1, line++)
		{
		char *p2;
		
		if (*p == ';')
		continue;		// comment
		
		p2 = strchr(p, '=');
		if (p2 == NULL)
			{
			error("%s:[_users_]:%d: invalid line format (no '=' character)", config, line);
			continue;
			}
		
		*p2 = '\0';		// temporary kill '='
		
		if (check_for_name(config, "_users_", p, name))
			sid_mask[sid_id / 8] |= 1 << (sid_id % 8);		// set bit in mask
		
		*p2 = '=';		// recover '=' to make strlen(p) works right
		
		sid_id++;
		}
	
	free(section);
}

BOOL	check_for_name(const char *config, const char *section, const char *value, const char *name)
{
	char buf[1024], *p, *p2;
	
	GetPrivateProfileString(section, value, "", buf, sizeof(buf), config);
	
	p = buf;
	
	if (strcmp(p, "*") == 0)
		return TRUE;			// *
	
	while (p != NULL)
		{
		
		p2 = strchr(p, ' ');
		if (p2 != NULL)
			{
			while (*p2 == ' ')
			*(p2++) = '\0';
			}
		
		if (*p != '\0' && strcmp(p, name) == 0)
			return TRUE;
		
		p = p2;
		}
	
	return FALSE;
}

void	get_traffic_stats(unsigned __int64 *stats)
{
	DWORD n;
	memset(stats, 0, sizeof(unsigned __int64) * TRAFFIC_MAX);
	DeviceIoControl(g_device, IOCTL_CMD_GET_COUNTERS, NULL, 0, stats, sizeof(unsigned __int64) * TRAFFIC_MAX, &n, NULL);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -