2013-02-12 2 views
0

Итак, я создаю утилиту для мониторинга файловой системы, реестра и сетевой активности (процесс мудрый, только активность по выбранным процессам). Я выполнил часть файловой системы и реестра, разработав драйвер minifilter. Однако я не уверен, как мне это сделать для сети. То, что я хочу сделать, очень похоже на то, что sysinternal's TCPView делает, однако я только хочу контролировать ESTABLISHED соединения выбранными процессами. Вот что я хочу, чтобы получить в режиме реального времени для каждого соединения:Какая технология/API/технология используется для мониторинга сети?

-Протокола (TCP или UDP)

-source порт

-Дистанционного IP и порт

- [опционально] количество байтов, переданных по определенному соединению с момента начала мониторинга

Что я должен использовать? я слышал о LSP, но, прочитав в нем немного дальше, я понял, что очень сложно писать правильно функционирующие LSP, не говоря уже о том, что едва ли можно найти материал, который можно было бы изучить с нуля. Кроме того, они устаревают. Проблема в том, что у меня есть только 2-3 недели времени, чтобы узнать + написать этот модуль. Из-за ограничения времени я, конечно же, не хочу идти на что-то вроде WFP, если у него нет очень хорошего учебника, и я не говорю о документации MSDN. Я не знаю, можно ли это «легко» сделать с помощью NDIS и т. Д.

Во всяком случае, что мне делать, где я должен сосредоточить свои усилия. Должен ли я рискнуть, узнав о LSP, или NDIS выполнит задачу или что-то еще. Сейчас я как бы бессознателен. Помогите мне здесь!

+0

Я также хочу, чтобы получить ProcessId/процесс для каждого соединения. Также я не хочу отслеживать «сетевой трафик», просто хочу получить конечные точки TCP и UDP в реальном времени, точно так же, как TCPView, за исключением только для подключений ESTABLISHED. – user1831704

ответ

2

Посмотрите на GetExtendedTcpTable и GetExtendedUdpTable. Эти API получат вам больше всего, что вам нужно. Но для того, чтобы все было интересно, демо-код, который я написал, вместо этого использует GetTcp6Table2.

#define WIN32_LEAN_AND_MEAN 
#define UNICODE 
#define _UNICODE 

#include <windows.h> 
#include <winsock2.h> 
#include <Ws2tcpip.h> 
#include <iphlpapi.h> 
#include <Tcpestats.h> 
#include <Tcpmib.h> 
#include <Mstcpip.h> 
#include <stdlib.h> 
#include <stdio.h> 

#pragma comment(lib, "iphlpapi.lib") 
#pragma comment(lib, "ws2_32.lib") 

PCWSTR 
StringFromState(MIB_TCP_STATE State) 
{ 
    switch (State) 
    { 
     case MIB_TCP_STATE_CLOSED: 
      return L"CLOSED"; 
     case MIB_TCP_STATE_LISTEN: 
      return L"LISTEN"; 
     case MIB_TCP_STATE_SYN_SENT: 
      return L"SYN_SENT"; 
     case MIB_TCP_STATE_SYN_RCVD: 
      return L"SYN_RCVD"; 
     case MIB_TCP_STATE_ESTAB: 
      return L"ESTAB"; 
     case MIB_TCP_STATE_FIN_WAIT1: 
      return L"FIN_WAIT1"; 
     case MIB_TCP_STATE_FIN_WAIT2: 
      return L"FIN_WAIT2"; 
     case MIB_TCP_STATE_CLOSE_WAIT: 
      return L"CLOSE_WAIT"; 
     case MIB_TCP_STATE_CLOSING: 
      return L"CLOSING"; 
     case MIB_TCP_STATE_LAST_ACK: 
      return L"LAST_ACK"; 
     case MIB_TCP_STATE_TIME_WAIT: 
      return L"TIME_WAIT"; 
     case MIB_TCP_STATE_DELETE_TCB: 
      return L"DELETE_TCB"; 
     default: 
      return L"[Unknown]"; 
    } 
} 

LPWSTR (NTAPI *pRtlIpv6AddressToStringW)(const IN6_ADDR *, LPWSTR); 

int __cdecl main() 
{ 
    ULONG r; 

    // We need to load this dynamically, because ntdll.lib doesn't export it 
    HMODULE ntdll = LoadLibrary(L"ntdll"); 
    pRtlIpv6AddressToStringW = (decltype(pRtlIpv6AddressToStringW))GetProcAddress(ntdll, "RtlIpv6AddressToStringW"); 

    // Initial guess for the table size 
    ULONG cbTable = 100; 
    MIB_TCP6TABLE2 *table = nullptr; 
    while (true) 
    { 
     table = (MIB_TCP6TABLE2*)malloc(cbTable); 
     if (!table) 
      return 1; 
     r = GetTcp6Table2(table, &cbTable, FALSE); 
     if (ERROR_INSUFFICIENT_BUFFER == r) 
     { 
      // Try again with bigger buffer 
      free(table); 
      continue; 
     } 
     else if (ERROR_SUCCESS == r) 
     { 
      break; 
     } 
     else 
     { 
      free(table); 
      wprintf(L"GetTcp6Table2 = %u\n", r); 
      return 1; 
     } 
    } 

    // Print table heading 
    wprintf(L"%56s %56s %10s %6s\n", L"Local endpoint", L"Remote endpoint", L"State", L"PID"); 
    for (ULONG i = 0; i < table->dwNumEntries; i++) 
    { 
     MIB_TCP6ROW2 const &entry = table->table[i]; 

     WCHAR localAddr[46]; 
     WCHAR remoteAddr[46]; 
     pRtlIpv6AddressToStringW(&entry.LocalAddr, localAddr); 
     pRtlIpv6AddressToStringW(&entry.RemoteAddr, remoteAddr); 

     WCHAR localEndpoint[56]; 
     WCHAR remoteEndpoint[56]; 
     swprintf_s(localEndpoint, L"[%s]:%-5u", localAddr, ntohs(entry.dwLocalPort)); 
     swprintf_s(remoteEndpoint, L"[%s]:%-5u", remoteAddr, ntohs(entry.dwRemotePort)); 

     wprintf(L"%56s %56s %10s %6u\n", 
       localEndpoint, remoteEndpoint, 
       StringFromState(entry.State), 
       entry.dwOwningPid); 
    } 

    free(table); 
    return 0; 
} 

Пример вывод (фактические адреса): анонимный

C:\>test.exe 
           Local endpoint        Remote endpoint  State PID 
            [::]:80          [::]:0  LISTEN 4 
            [::]:135          [::]:0  LISTEN 980 
            [::]:445          [::]:0  LISTEN 4 
            [::]:1025         [::]:0  LISTEN 692 
[2001:xxxx:x:xxx:x:xxxx:xxx.xx.xxx.xx]:6044     [xxxx:xxx:xxxx:xxxx::x]:443  ESTAB 3248 
[2001:xxxx:x:xxx:x:xxxx:xxx.xx.xxx.xx]:6045     [xxxx:xxx:xxxx:xxxx::x]:443  ESTAB 3248 
    [2001:xxxx:xx:x:xxxx:xxxx:xxxx:xxxx]:53759 [2001:xxxx:xx:xxxx:xxx:xxxx:xxxx:xxxx]:135 TIME_WAIT 0 
+0

Спасибо за помощь! ... это очень помогает! – user1831704

0

Звучит так, как будто вы хотите что-то вроде winpcap, что и использует wirehark.

http://www.winpcap.org/

Также NetStat код из ReactOS может быть интересно

http://doxygen.reactos.org/dd/d3f/netstat_8c_source.html

+0

Пример netstat использует API-интерфейс IP-помощника, я думаю, но я не думаю, что могу получить идентификаторы процессов или количество байтов, переданных с ним, как это делает TCPView? Также не winpcap больше для захвата и мониторинга пакетов. Мне просто нужны конечные точки TCP и UDP, и они тоже в режиме реального времени, когда любой процесс инициирует соединение вместе с именем или идентификатором процессов. – user1831704

+0

Dunno Я мог бы барабанить пару для Linux (Nagios и Nethogs, я думаю) ... но не знаю, есть ли для Windows. – cb88

+0

Без проблем! Спасибо за помощь! – user1831704