Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Obtener puertos abiertos TCP/IP por cada programa

Estas en el tema de Obtener puertos abiertos TCP/IP por cada programa en el foro de C/C++ en Foros del Web. Hola quiero hacer una pequeña aplicación en C++ a nivel de consola que me permita ver las pilas TCP/IP de todos los puertos abiertos de ...
  #1 (permalink)  
Antiguo 28/08/2013, 16:01
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Pregunta Obtener puertos abiertos TCP/IP por cada programa

Hola quiero hacer una pequeña aplicación en C++ a nivel de consola que me permita ver las pilas TCP/IP de todos los puertos abiertos de todos los programas que se ejecutan en mi computadora algo parecido al comando netstat pero a diferencia que saber que programa esta usando cada puerto; alguien sabe si existe alguna librería que pueda usar o donde puedo obtener documentación para elaborar mi pequeña aplicación.

Última edición por EL_DOC; 29/08/2013 a las 08:14
  #2 (permalink)  
Antiguo 29/08/2013, 22:27
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Buscando en la red encontré un código de alguien que está haciendo casi lo mismo pero hay ciertas cosas que no logro comprender del código si alguien me ayuda a comprender el código se los agradecería, el código es el siguiente:

string Port::GetListOfTcpPorts()

{
string ApplicationName = "";
string result = "";
string aux = "";
string RemotePort = "";
DWORD (WINAPI *pGetExtendedTcpTable)(
PVOID pTcpTable,
PDWORD pdwSize,
BOOL bOrder,
ULONG ulAf,
TCP_TABLE_CLASS TableClass,
ULONG Reserved
);
MIB_TCPTABLE_OWNER_PID *pTCPInfo;
MIB_TCPROW_OWNER_PID *owner;
DWORD size;
DWORD dwResult;

HMODULE hLib = LoadLibrary("iphlpapi.dll");

pGetExtendedTcpTable = (DWORD (WINAPI *)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG))
GetProcAddress(hLib, "GetExtendedTcpTable");

dwResult = pGetExtendedTcpTable(NULL, &size, false, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
pTCPInfo = (MIB_TCPTABLE_OWNER_PID*)malloc(size);
dwResult = pGetExtendedTcpTable(pTCPInfo, &size, false, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
for (DWORD dwLoop = 0; dwLoop < pTCPInfo->dwNumEntries; dwLoop++)
{
owner = &pTCPInfo->table[dwLoop];
ApplicationName = GetNameByPID(owner->dwOwningPid);
OpenedPort = convertInt(ntohs(owner->dwLocalPort));
RemotePort = convertInt(ntohs(owner->dwRemotePort));
aux = "TCP ; " + OpenedPort + ";"+ RemotePort+";"+ ApplicationName + "\n";
result = result + aux;

}
return result;
}
  #3 (permalink)  
Antiguo 29/08/2013, 22:31
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Cita:
Iniciado por EL_DOC Ver Mensaje
Buscando en la red encontré un código de alguien que está haciendo casi lo mismo pero hay ciertas cosas que no logro comprender del código si alguien me ayuda a comprender el código se los agradecería, el código es el siguiente:

string Port::GetListOfTcpPorts()

{
string ApplicationName = "";
string result = "";
string aux = "";
string RemotePort = "";
DWORD (WINAPI *pGetExtendedTcpTable)(
PVOID pTcpTable,
PDWORD pdwSize,
BOOL bOrder,
ULONG ulAf,
TCP_TABLE_CLASS TableClass,
ULONG Reserved
);
MIB_TCPTABLE_OWNER_PID *pTCPInfo;
MIB_TCPROW_OWNER_PID *owner;
DWORD size;
DWORD dwResult;

HMODULE hLib = LoadLibrary("iphlpapi.dll");

pGetExtendedTcpTable = (DWORD (WINAPI *)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG))
GetProcAddress(hLib, "GetExtendedTcpTable");

dwResult = pGetExtendedTcpTable(NULL, &size, false, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
pTCPInfo = (MIB_TCPTABLE_OWNER_PID*)malloc(size);
dwResult = pGetExtendedTcpTable(pTCPInfo, &size, false, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
for (DWORD dwLoop = 0; dwLoop < pTCPInfo->dwNumEntries; dwLoop++)
{
owner = &pTCPInfo->table[dwLoop];
ApplicationName = GetNameByPID(owner->dwOwningPid);
OpenedPort = convertInt(ntohs(owner->dwLocalPort));
RemotePort = convertInt(ntohs(owner->dwRemotePort));
aux = "TCP ; " + OpenedPort + ";"+ RemotePort+";"+ ApplicationName + "\n";
result = result + aux;

}
return result;
}

Están usando la función GetExtendedTcpTable de la librería Iphlpapi.lib
  #4 (permalink)  
Antiguo 01/09/2013, 12:59
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Pongo una miniaplicacion que seguramente te solucionará muchas de las dudas:

Código C:
Ver original
  1. int main() {
  2.     MIB_TCPTABLE_OWNER_PID *tcp_table;
  3.     MIB_TCPROW_OWNER_PID *proc_owner;
  4.     unsigned long dw;
  5.     HANDLE hproc;
  6.     char base_name[512];
  7.     unsigned char ipv4_address[4] = {0,0,0,0};
  8.     int q;
  9.  
  10.     //determinas tamaño de la struct MIB_TCPTABLE_OWNER_PID y reserva memoria
  11.     GetExtendedTcpTable(0, &dw, 0, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
  12.     tcp_table = (MIB_TCPTABLE_OWNER_PID*)malloc(dw);
  13.  
  14.     //consulta las tablas
  15.     GetExtendedTcpTable(tcp_table, &dw, 0, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
  16.    
  17.     //recorre las tablas
  18.     for(dw = 0; dw < tcp_table->dwNumEntries; dw++) {
  19.         proc_owner = &tcp_table->table[dw];
  20.  
  21.         if((hproc = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, 0, proc_owner->dwOwningPid))) {
  22.  
  23.             if(GetModuleBaseName(hproc, 0, base_name, sizeof(base_name))) {
  24.                 printf("%s\n", base_name);
  25.  
  26.                 for(q = 0; q < 4; q++) {
  27.                     ipv4_address[q] = ( proc_owner->dwLocalAddr >> (q*8) ) & 0xFF;
  28.                 }
  29.                 printf("\tLocal\t%d.%d.%d.%d : %d\n", ipv4_address[0], ipv4_address[1], ipv4_address[2], ipv4_address[3], (int)ntohs(proc_owner->dwLocalPort));
  30.  
  31.                 for(q = 0; q < 4; q++) {
  32.                     ipv4_address[q] = ( proc_owner->dwRemoteAddr >> (q*8) ) & 0xFF;
  33.                 }
  34.                 printf("\tRemoto\t%d.%d.%d.%d : %d\n", ipv4_address[0], ipv4_address[1], ipv4_address[2], ipv4_address[3], (int)ntohs(proc_owner->dwRemotePort));
  35.  
  36.                 printf("\tEstado\t%d", proc_owner->dwState);
  37.  
  38.                 printf("\n\n");
  39.             }
  40.             CloseHandle(hproc);
  41.         }
  42.     }
  43.  
  44.     return 0;
  45. }

La funcion GetExtendedTcpTable está en iphlpapi.h, la funcion GetModuleBaseName está en psapi.h, a su vez estas cabeceras incluyen otras cabeceras con tipos de datos definidos en windef.h y no se donde mas por lo que tambien tendras que incluir windows.h Si ademas quieres trabajar con funciones de red cambia windows.h por winsock2.h En este caso lo unico que hago en red es determinar la IP a partir del numero, para eso no hace falta iniciar la libreria de sockets. No olvides linkar las librerias de las cabeceras.

Saludos
  #5 (permalink)  
Antiguo 05/09/2013, 15:06
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Saludos Vosk ya estoy implementando mi función pero tengo un problema y es a la hora de recorrer la tabla que me devuelve GetExtendedTcpTable no se que hice mal en el for si me puedes ayudar te lo agradecería

Código C++:
Ver original
  1. for(int i=0; i < (int) pTcpTable->dwNumEntries; i++)

pTcpTable no es el parámetro yo declaré la variable con el mismo nombre
PVOID pTclTable

Última edición por EL_DOC; 05/09/2013 a las 15:24
  #6 (permalink)  
Antiguo 06/09/2013, 09:17
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Pregunta Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Hola Vosk ya implementé la función GetExtendedTcpTable y comparé los PId que me retorna con los del ProcessExplorer para ver si me retorna todos los procesos y no me muestra todos los procesos que me muestra el processExplorer que son iguales a los procesos que muestra el administrador de windows tal vez puedas ayudarme o si alguien sabe el problema se los agradecería.
  #7 (permalink)  
Antiguo 06/09/2013, 12:50
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Código C:
Ver original
  1. for(int i=0; i < (int) pTcpTable->dwNumEntries; i++)

Ojo, dwNumEntries en la struct MIB_TCPTABLE_OWNER_PID es DWORD (unsigned long).


"...no me muestra todos los procesos..."

Consulta los argumentos validos en la referencia de msdn http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx, cambia y/o combina el flag de ulAf y la tabla requerida. En el caso de mi ejemplo que colgué estoy pidiendo los pIDs de todos los procesos abiertos en red y usando el protocolo IPv4.

Saludos
vosk
  #8 (permalink)  
Antiguo 06/09/2013, 13:11
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Si gracias, una consulta y si quiero saber el protocolo si es TCP o UDP porque en la estructura de la tabla que devuelve no retorna el protocolo
  #9 (permalink)  
Antiguo 06/09/2013, 14:24
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Vas a tener que estar un poco mas al tanto con eso :) , pero tranquilo que tiene facil solucion: la funcion GetExtendedTcpTable es (tal como el nombre indica) para tcp, la funcion GetExtendedUdpTable es para udp. En msdn tienes la referencia de ambas.

Saludos
vosk
  #10 (permalink)  
Antiguo 06/09/2013, 15:24
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

ahh gracias en otras palabras no incluye en la estructura de la tabla un campo protocol porque lo que me devuelve en el caso de GetExtendedTcpTable son sólo para los de este protocolo y la función GetExtendedUdpTable son para los protocolos udp
  #11 (permalink)  
Antiguo 09/09/2013, 08:16
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Vosk una pregunta para la función GetExtendedUdpTable no hay un enum para que me devuelva todos las conexiones así como para tcp que está el enum "TCP_TABLE_OWNER_PID_ALL" para conexiones udp estaba revisando la documentación y sólo está "UDP_TABLE_ONER_PID" disculpa las molestias
  #12 (permalink)  
Antiguo 09/09/2013, 11:07
 
Fecha de Ingreso: junio-2008
Mensajes: 109
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

tengo otra consulta, hay algo que no comprendo bien del código que pusiste arriba porque utilizas las funciones OpenProcess y GetModuleName en las siguientes líneas:
Código C++:
Ver original
  1. if((hproc = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, 0, proc_owner->dwOwningPid))) {
  2.  
  3.             if(GetModuleBaseName(hproc, 0, base_name, sizeof(base_name))) {
  4.                 printf("%s\n", base_name);
  5.  
  6.                 for(q = 0; q < 4; q++) {
  7.                     ipv4_address[q] = ( proc_owner->dwLocalAddr >> (q*8) ) & 0xFF;
  8.                 }
  9.                 printf("\tLocal\t%d.%d.%d.%d : %d\n", ipv4_address[0], ipv4_address[1], ipv4_address[2], ipv4_address[3], (int)ntohs(proc_owner->dwLocalPort));
  10.  
  11.                 for(q = 0; q < 4; q++) {
  12.                     ipv4_address[q] = ( proc_owner->dwRemoteAddr >> (q*8) ) & 0xFF;
  13.                 }
  #13 (permalink)  
Antiguo 09/09/2013, 15:19
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

Por lo de las UDP_TABLE_ONER_PID no puedo ayudarte porque solo he usado las tcp, pero tambien le echaré un vistazo a ver si veo algo.

La funcion OpenProcess retorna un handler de un proceso activo, acepta tres argumentos: un flag (o una combinacion) de acceso, un boleano que indica si el handler retornado puede ser heredado por procesos derivados del proceso que pide el handler, y el identificador de proceso. En el ejemplo pido un handler con acceso de lectura, no heredable, para el proceso cuyo id se indica en la tabla de procesos. Es la consulta minima segura para obtener un manejador (handler) de proceso (puede que haya otra forma) para consultas simples.

El handler me sirve para llamar a cualquier funcion en la que se requiera un manejador con permiso de acceso a informacion (query) y permiso de lectura, por eso necsito los flags PROCESS_QUERY_INFORMATION y PROCESS_VM_READ. Algunas funciones solo requieren el flag de lectura, etc... Los permisos de los handlers que se usan en las funciones estan indicados en la referencia de cada funcion (en el manual de referencia o en msdn).

En este caso quiero el nombre base de la instancia de la aplicacion, por eso ejecuta GetModuleBaseName. Esta funcion requiere un handler con permisos (como minimo) de acceso y de lectura (los que pedí en OpenProcess), el segundo argumento es el manipulador del modulo (si indico nulo me retorna el nombre del ejecutable desde el que se creó esa instancia), el tercer argumento es un buffer de texto donde copiará el nombre, y el cuarto indica el tamaño del buffer. Si quieres obtener la ruta absoluta al ejecutable desde el que se creo el proceso de la instancia puedes usar GetModuleFileName, tienes la referencia en msdn).

Código C:
Ver original
  1. hproc = OpenProcess(//solicito un handler
  2.     PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,//con permiso de acceso y de lectura
  3.     0,//no heredable
  4.     proc_owner->dwOwningPid//que tiene este identificador
  5.     );
  6.  
  7. //en caso de error el handler es nulo
  8. //el handler no nulo obtenido lo uso para recuperar el nombre del ejecutable
  9. GetModuleBaseName(
  10.     hproc, //manejador con permiso de acceso y lectura
  11.     0, //manejador del modulo, pero no quiero el nombre del modulo sino del ejecutable
  12.     base_name, //buffer de destino
  13.     sizeof(base_name)//tamaño del buffer
  14.     );

Saludos
vosk
  #14 (permalink)  
Antiguo 09/09/2013, 15:37
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Obtener puertos abiertos TCP/IP por cada programa

"...estaba revisando la documentación y sólo está "UDP_TABLE_ONER_PID"..."

Copio y pego lo que veo en la referencia:

Código C:
Ver original
  1. This table contains UDP endpoints for IPv4 that have been bound to an address. It should be noted that an application can create a UDP socket and bind it to an address for the sole purpose of sending a UDP datagram, with no intention of receiving packets using this socket (functioning as a listener).

Entiendo que MIB_UDPTABLE_OWNER_PID te va a listar todas las disponibles a causa del funcionamiento del procolo udp: abres para envio, envias y cierras.

Saludos
vosk

Etiquetas: cada, programa, puertos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:12.