roPcap
roPcap se utiliza para analizar archivos PCAP en busca de flujos de tráfico UDP, prepararlos para la reproducción (filtrando y reescribiendo encabezados opcionalmente), reproducirlos en una interfaz de red con sincronización sin deriva y extraer flujos de carga útil UDP sin procesar de capturas PCAP. Está disponible a partir de BOS 9.1.143.
Si se establece un puerto de mensajes mediante SetPort(), el objeto publica mensajes roPcapEvent para eventos del ciclo de vida de la reproducción (iniciada, detenida, repetida en bucle, underrun, descartada).
Solo puede existir una instancia de roPcap a la vez. CreateObject("roPcap") devuelve Inválido si otra instancia ya está activa.
Si utiliza tmp:/ debe tener en cuenta el tamaño del PCAP. Si es grande, no cabrá en un tmp:/ basado en RAM y debería usar almacenamiento local en su lugar (por ejemplo, sd:/)
ifPcap
Analyze(filename As String) As Object
Escanea todos los paquetes en nombre de archivo y devuelve un roArray de roAssociativeArray, una entrada por cada flujo UDP encontrado. Los flujos se ordenan por cantidad de paquetes en orden descendente. Devuelve una matriz vacía si el archivo no puede abrirse o no contiene flujos UDP.
Cada entrada en la matriz devuelta contiene las siguientes claves:
Clave | Tipo | Descripción |
|---|---|---|
src_ip | String | Dirección IPv4 de origen |
src_port | Integer | Puerto UDP de origen |
dst_ip | String | Dirección IPv4 de destino |
dst_port | Integer | Puerto UDP de destino |
packet_count | Integer | Número de paquetes UDP en el flujo |
Prepare(params As roAssociativeArray) As Integer
Filtra paquetes del PCAP de entrada y escribe un PCAP de salida listo para reproducción, reemplazando opcionalmente los encabezados de IP de destino y puerto UDP. La dirección MAC de origen y la dirección IP de origen de cada paquete de salida siempre se reescriben con los valores de la interfaz de red especificada.
Si RewriteOutputDestAddress es una dirección multicast, la MAC de destino se deriva utilizando la fórmula RFC 1112. Si es una dirección unicast, la MAC de destino se resuelve mediante la caché ARP del kernel; el destino ya debe ser accesible (por ejemplo, mediante un ping previo) antes de llamar a Prepare().
Devuelve un código entero PcapEngineError; 0 en caso de éxito. Consulte Códigos de error.
Parámetros obligatorios:
Clave | Tipo | Descripción |
|---|---|---|
Archivo de entrada | String | Ruta al archivo PCAP de origen |
ArchivoDeSalida | String | Ruta para escribir el PCAP preparado (debe ser diferente de Archivo de entrada) |
Interfaz | String | Nombre de la interfaz de red utilizada para resolver la MAC e IP de origen (p. ej. "eth0") |
Parámetros de filtro opcionales:
Clave | Tipo | Descripción |
|---|---|---|
FilterInputSourceAddress | String | Conservar solo los paquetes con esta dirección IPv4 de origen |
FilterInputSourcePort | Integer | Conservar solo los paquetes UDP de este puerto de origen (1024–65535) |
FilterInputDestAddress | String | Conservar solo los paquetes con esta dirección IPv4 de destino |
FilterInputDestPort | Integer | Conservar solo los paquetes UDP hacia este puerto de destino (1024–65535) |
AutoFlowSelect | Boolean | Vea la nota a continuación |
Parámetros de reescritura opcionales:
Clave | Tipo | Descripción |
|---|---|---|
RewriteOutputDestAddress | String | Reescribir la dirección IP de destino (unicast o multicast) |
RewriteOutputDestPort | Integer | Reescribir el puerto UDP de destino (1024–65535) |
Comportamiento predeterminado de AutoFlowSelect: Cuando no se proporcionan claves Campo de filtro* keys, AutoFlowSelect toma el valor predeterminado de verdadero: el flujo con el mayor número de paquetes se selecciona automáticamente. Cuando cualquier clave Campo de filtro* está presente, AutoFlowSelect toma el valor predeterminado de falso: si los criterios de filtro coinciden con más de un flujo, Prepare() devuelve PCAP_ERR_AMBIGUOUS_FLOW (-7) en lugar de seleccionar uno. Una clave explícita de AutoFlowSelect siempre reemplaza el valor predeterminado.
ExtractStream(params As roAssociativeArray) As Integer
Concatena los bytes de carga útil UDP sin procesar de cada paquete coincidente en Archivo de entrada y los escribe en ArchivoDeSalida. No se requiere una llamada previa a Prepare(). Esto es útil para recuperar el flujo de bytes original de una captura UDP; por ejemplo, extraer un archivo MPEG-TS de una grabación TS-over-UDP.
Los criterios de filtro deben resolverse exactamente en un flujo UDP. Use AutoFlowSelect para seleccionar automáticamente el flujo con el mayor recuento cuando el filtro es amplio.
Devuelve un código entero PcapEngineError; 0 en caso de éxito. Consulte Códigos de error. Puede devolver PCAP_ERR_READ_FAILED (-8) si el archivo de entrada está dañado o truncado.
Parámetros obligatorios:
Clave | Tipo | Descripción |
|---|---|---|
Archivo de entrada | String | Ruta al archivo PCAP de origen |
ArchivoDeSalida | String | Ruta donde escribir el flujo extraído; se crea o se trunca |
Parámetros de filtro opcionales:
Igual que en Prepare(): FilterInputSourceAddress, FilterInputSourcePort, FilterInputDestAddress, FilterInputDestPort, AutoFlowSelect (misma lógica predeterminada que Prepare()).
Start(params As roAssociativeArray) As Boolean
Comienza a reproducir el archivo PCAP preparado en la interfaz de red especificada. Los paquetes se sincronizan según sus intervalos originales entre paquetes utilizando marcas de tiempo monotónicas absolutas para que el exceso de tiempo en un paquete no pueda acumularse como deriva en los paquetes posteriores.
Bloquea hasta que el hilo del remitente se haya iniciado o haya fallado al iniciarse. Publica un roPcapEvent con el tipo 1 (Started) en el puerto de mensajes en caso de éxito.
Devuelve Verdadero en caso de éxito; Falso si no se pudo iniciar el hilo del remitente.
Parámetros obligatorios:
Clave | Tipo | Descripción |
|---|---|---|
Nombre del archivo | String | Ruta al archivo PCAP preparado para reproducir |
Interfaz | String | Nombre de la interfaz de red desde la que se enviará (p. ej., "eth0") |
Parámetros opcionales:
Clave | Tipo | Descripción |
|---|---|---|
LoopCount | Integer | Número de veces que se recorrerá el archivo en bucle; 0 (predeterminado) se repite indefinidamente |
PrecargarEnMemoria | Boolean | Si Verdadero, carga el archivo completo en RAM antes de que comience la reproducción (limitado al 50 % de la RAM total del sistema). Use esto cuando se requiera una temporización determinística por paquete y el archivo quepa cómodamente en la memoria. El valor predeterminado es el modo de streaming, que lee desde el disco con un búfer de lectura anticipada de 20 MiB y es adecuado para cualquier tamaño de archivo. |
Stop() As Void
Devuelve Verdadero mientras el hilo emisor está ejecutando el bucle de reproducción. Devuelve Falso una vez que se agota el recuento de bucles, se llama a Stop() o se produce un error fatal después de que Start() devolvió Verdadero.
GetStats() As roAssociativeArray
Devuelve una instantánea de las estadísticas de reproducción. Es seguro llamarlo en cualquier momento, incluso mientras la reproducción está en ejecución.
Clave | Tipo | Descripción |
|---|---|---|
packets_sent | Integer | Tramas transmitidas correctamente desde la última llamada a Start() |
packets_dropped | Integer | Tramas descartadas debido a que no había espacio de búfer o por ocupado, desde la última llamada a Start() |
loops_completed | Integer | Pasadas de bucle completas que finalizaron correctamente |
subdesbordamientos | Integer | Veces que el búfer de lectura anticipada de streaming estuvo vacío; siempre 0 cuando PrecargarEnMemoria es Verdadero |
elapsed_ms | Integer | Milisegundos de reloj transcurridos desde la última llamada a Start() o ResetStats(); 0 cuando está detenido |
timing_sample_count | Integer | Número de paquetes que contribuyen a los campos de temporización a continuación |
timing_mean_us | Integer | Error de temporización medio en microsegundos; positivo significa que el paquete salió tarde, negativo significa que salió temprano |
timing_min_us | Integer | Error de temporización mínimo (más temprano) en microsegundos |
timing_max_us | Integer | Error de temporización máximo (más tardío) en microsegundos |
timing_stddev_us | Integer | Desviación estándar de muestra del error de temporización en microsegundos |
Los campos de temporización son 0 hasta que se haya enviado al menos un paquete.
ResetStats() como Void
Restablece todas las estadísticas de reproducción a cero. Es seguro llamarlo mientras la reproducción está en ejecución. Los contadores actualizados por el hilo de reproducción después de la llamada reflejan solo la actividad desde el restablecimiento.
ifMessagePort
SetPort(port As roMessagePort)
Publica mensajes de tipo roPcapEvent en el puerto de mensajes adjunto.
ifUserData
SetUserData(user_data As Object)
Establece los datos de usuario que se devolverán cuando se generen eventos.
GetUserData() As Object
Devuelve los datos de usuario establecidos previamente mediante SetUserData(). Devuelve Inválido si no se han establecido datos.
roPcapEvent
roPcapEvent se publica en el puerto de mensajes establecido en roPcap siempre que ocurre un evento del ciclo de vida de reproducción.
ifPcapEvent
GetInt() As Integer
Devuelve el código de tipo de evento:
Valor | Nombre | Descripción |
|---|---|---|
1 | Iniciado | El hilo de reproducción se inició y está enviando paquetes |
2 | Detenido | El hilo de reproducción se detuvo (se agotó el recuento de bucles, se llamó a Stop() o se produjo un error fatal) |
3 | En bucle | Se completó una pasada completa; GetData() devuelve el número de bucle indexado desde 1 |
4 | Subdesbordamiento | El búfer de lectura anticipada de streaming estaba vacío; el tiempo de reproducción puede haberse visto afectado |
5 | Descartado | Se descartó un paquete; GetData() devuelve el recuento acumulado de descartes en el momento del descarte |
GetData() As Integer
Devuelve datos específicos del evento. Consulte la tabla anterior. Devuelve 0 para eventos en los que no se aplican datos adicionales.
Códigos de error
Prepare() y ExtractStream() devuelven uno de los siguientes códigos enteros:
Valor | Nombre | Descripción |
|---|---|---|
0 | PCAP_OK | Correcto |
-1 | PCAP_ERR_FILE_NOT_FOUND | Archivo de entrada no existe o no puede abrirse |
-2 | PCAP_ERR_INVALID_FLOW_PORT | Un valor de puerto está fuera del rango válido [1024, 65535] |
-3 | PCAP_ERR_WRITE_FAILED | ArchivoDeSalida no pudo escribirse |
-4 | PCAP_ERR_INVALID_INTERFACE | El nombre de la interfaz es inválido o no se encontró en el sistema |
-5 | PCAP_ERR_INVALID_PARAM | Se proporcionó un parámetro inválido: formato de dirección IP incorrecto, Archivo de entrada y ArchivoDeSalida son la misma ruta, o una dirección unicast RewriteOutputDestAddress no pudo resolverse a una MAC mediante ARP |
-6 | PCAP_ERR_NO_MATCHING_FLOW | Los criterios de filtro no coincidieron con ningún flujo; proporcione un filtro menos restrictivo o verifique que el archivo de entrada contenga el tráfico esperado |
-7 | PCAP_ERR_AMBIGUOUS_FLOW | Los criterios de filtro coincidieron con más de un flujo distinto; ajuste el filtro para seleccionar exactamente uno, o establezca AutoFlowSelect: Verdadero para elegir automáticamente el flujo con el mayor conteo |
-8 | PCAP_ERR_READ_FAILED | ExtractStream() solamente: el archivo de entrada está dañado o truncado |
Ejemplos
Analizar un archivo PCAP
Imprima todos los flujos UDP encontrados en un archivo de captura:
pcap = CreateObject("roPcap")
flows = pcap.Analyze("SD:/capture.pcap")
for each flow in flows
print flow.src_ip + ":" + flow.src_port.ToStr() + " -> " + _
flow.dst_ip + ":" + flow.dst_port.ToStr() + _
" packets=" + flow.packet_count.ToStr()
end forPreparar y reproducir con manejo de eventos
Seleccione un flujo, reescríbalo a un grupo multicast local y reprodúzcalo tres veces mientras supervisa eventos:
pcap = CreateObject("roPcap")
port = CreateObject("roMessagePort")
pcap.SetPort(port)
' Step 1 — inspect the capture to find the flow
flows = pcap.Analyze("SD:/source.pcap")
if flows.Count() = 0
print "No UDP flows found"
stop
end if
' Step 2 — prepare: filter to the largest flow, rewrite destination
params = CreateObject("roAssociativeArray")
params.InputFile = "SD:/source.pcap"
params.OutputFile = "tmp:/prepared.pcap"
params.Interface = "eth0"
' AutoFlowSelect defaults to true when no FilterInput* keys are given,
' so the highest-count flow is selected automatically.
params.RewriteOutputDestAddress = "239.1.2.3"
params.RewriteOutputDestPort = 1234
result = pcap.Prepare(params)
if result <> 0
print "Prepare failed: " + result.ToStr()
stop
end if
' Step 3 — replay three times
startParams = CreateObject("roAssociativeArray")
startParams.Filename = "tmp:/prepared.pcap"
startParams.Interface = "eth0"
startParams.LoopCount = 3
if not pcap.Start(startParams)
print "Start failed"
stop
end if
' Step 4 — event loop
while True
msg = Wait(0, port)
if type(msg) = "roPcapEvent"
select case msg.GetInt()
case 3 ' Looped
print "Completed loop " + msg.GetData().ToStr()
case 5 ' Dropped
print "Drop count: " + msg.GetData().ToStr()
case 2 ' Stopped
print "Replay finished"
exit while
end select
end if
end while
stats = pcap.GetStats()
print "Sent=" + stats.packets_sent.ToStr() + _
" Dropped=" + stats.packets_dropped.ToStr() + _
" Underruns=" + stats.underruns.ToStr()Extraer un flujo sin procesar de un PCAP
Recupere un archivo MPEG-TS de una captura TS-over-UDP. No se necesita ninguna Prepare() ni interfaz de red:
pcap = CreateObject("roPcap")
params = CreateObject("roAssociativeArray")
params.InputFile = "SD:/recording.pcap"
params.OutputFile = "SD:/extracted.ts"
' AutoFlowSelect defaults to true when no FilterInput* keys are given.
' Set explicit filter keys to target a specific flow in a multi-flow capture.
params.FilterInputDestAddress = "239.10.20.30"
params.FilterInputDestPort = 1234
' AutoFlowSelect defaults to false because FilterInput* keys are present;
' set it explicitly to true to auto-pick if the filter still matches multiple flows.
params.AutoFlowSelect = True
result = pcap.ExtractStream(params)
if result = 0
print "Stream extracted successfully"
else
print "ExtractStream failed: " + result.ToStr()
end if