2013-02-12 2 views
0

Bon, je suis en train de créer un utilitaire pour surveiller l'activité du système de fichiers, du registre et du réseau (pour ce qui est du processus, seule l'activité des processus sélectionnés). J'ai accompli la partie d'activité de système de fichiers et de registre en développant un conducteur de minifilter. Cependant, je suis incertain quant à la façon dont je devrais le faire pour le réseau. Ce que je veux faire ressemble beaucoup à ce que fait TCPView de sysinternal, cependant je veux seulement surveiller les connexions ESTABLISHED par les processus sélectionnés. Voici ce que je veux obtenir en temps réel pour chaque connexion:Quelle technologie/API/technique utiliser pour la surveillance du réseau?

-protocol (TCP ou UDP)

Port -source

IP et le port -remote

- montant [en option] des octets transférés sur une connexion particulière à partir du moment où la surveillance a commencé

Que dois-je utiliser? J'ai entendu parler des LSP, mais en lisant un peu plus loin, je me suis rendu compte qu'il est TRÈS difficile d'écrire des LSP fonctionnant correctement, sans parler du fait qu'il n'y a pratiquement pas de matériel disponible pour apprendre à partir de zéro. Aussi qu'ils deviennent obsolètes. Le problème est que je n'ai que 2 à 3 semaines de temps pour apprendre + écrire ce module. En raison de la limite de temps, je ne veux certainement pas opter pour quelque chose comme le PAM, à moins qu'il y ait un très bon tutoriel à ce sujet, et je ne parle pas de la documentation MSDN. Je ne sais pas si cela pourrait être "facilement" fait en utilisant NDIS

De toute façon, alors que dois-je faire, où devrais-je concentrer mes efforts. Devrais-je prendre le risque d'en apprendre davantage sur les fournisseurs de services linguistiques ou NDIS accomplirait-il la tâche ou quelque chose d'autre? Je suis un peu désemparé en ce moment. Aidez-moi ici!

+0

Je veux aussi processID/processus pour chaque connexion. Aussi, je ne veux pas surveiller le «trafic réseau», je veux juste obtenir les points de terminaison TCP et UDP en temps réel, tout comme TCPView, sauf pour les connexions ESTABLISHED. – user1831704

Répondre

2

Regardez GetExtendedTcpTable et GetExtendedUdpTable. Ces API vous apporteront la plupart de ce dont vous avez besoin. Mais juste pour garder les choses intéressantes, le code de démo que j'ai écrit utilise GetTcp6Table2 à la place.

#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; 
} 

Exemple de sortie (adresses réelles anonymisées):

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

Merci pour l'aide man! ... cela aide beaucoup! – user1831704

0

Cela me semble que vous voulez quelque chose comme winpcap qui est ce que wireshark utilise.

http://www.winpcap.org/

également le code netstat de ReactOS pourrait être intéressant

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

+0

L'exemple netstat utilise l'API IP Helper je pense, mais je ne pense pas que je peux obtenir les ID de processus ou la quantité d'octets transférés en utilisant comme TCPView fait? Winpcap n'est pas plus pour la capture et la surveillance de paquets. Je veux juste les points de terminaison TCP et UDP, et ceux-là aussi en temps réel, quand un processus initie une connexion avec le nom ou l'identifiant du processus. – user1831704

+0

Je ne pourrais pas faire un couple pour Linux (Nagios et Nethogs je pense) ... mais je ne sais pas s'il y en a pour Windows. – cb88

+0

Pas de problème! Merci pour l'aide! – user1831704

Questions connexes