Skip to content

Instantly share code, notes, and snippets.

@rene-d
Created April 12, 2025 04:50
Show Gist options
  • Save rene-d/ec17cfe09a1482cb958d566c84bde185 to your computer and use it in GitHub Desktop.
Save rene-d/ec17cfe09a1482cb958d566c84bde185 to your computer and use it in GitHub Desktop.
[package]
name = "pcape"
version = "0.1.0"
edition = "2024"
[dependencies]
[[bin]]
name = "pcape"
path = "pcape.rs"
// cc -o pcape -Wall -O2 pcape.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
struct pcap_header_t
{
uint32_t magic_number;
uint16_t version_major;
uint16_t version_minor;
int32_t thiszone;
uint32_t sigfigs;
uint32_t snaplen;
uint32_t network;
};
struct packet_header_t
{
uint32_t ts_sec;
uint32_t ts_usec;
uint32_t incl_len;
uint32_t orig_len;
};
int main(int argc, char *argv[])
{
if (argc != 2)
exit(EXIT_FAILURE);
FILE *file = fopen(argv[1], "r+b");
if (file == NULL)
exit(EXIT_FAILURE);
struct pcap_header_t pcap_header;
struct packet_header_t pkt_header;
// lit l'entête global du fichier pcap
if (fread(&pcap_header, sizeof(pcap_header), 1, file) != 1)
{
fclose(file);
exit(EXIT_FAILURE);
}
// vérification du format
if (pcap_header.magic_number != 0xa1b2c3d4)
{
fclose(file);
exit(EXIT_FAILURE);
}
uint32_t pkt_num = 0;
while (true)
{
// lit l'entête du paquet
if (fread(&pkt_header, sizeof(pkt_header), 1, file) != 1)
break;
pkt_header.ts_usec = ++pkt_num;
// revient en arrière pour réécrire l'entête modifiée
if (fseek(file, -sizeof(pkt_header), SEEK_CUR) != 0)
break;
if (fwrite(&pkt_header, sizeof(pkt_header), 1, file) != 1)
break;
// saute le contenu pour passer au paquet suivant
if (fseek(file, pkt_header.incl_len, SEEK_CUR) != 0)
break;
}
fclose(file);
printf("fichier %s modifié. %u paquets écrits\n", argv[1], pkt_num);
return 0;
}
package main
import (
"encoding/binary"
"fmt"
"os"
)
type PcapHeader struct {
MagicNumber uint32
VersionMajor uint16
VersionMinor uint16
ThisZone int32
SigFigs uint32
SnapLen uint32
Network uint32
}
type PacketHeader struct {
TsSec uint32
TsUsec uint32
InclLen uint32
OrigLen uint32
}
func main() {
if len(os.Args) != 2 {
os.Exit(1)
}
filename := os.Args[1]
file, err := os.OpenFile(filename, os.O_RDWR, 0644)
if err != nil {
os.Exit(1)
}
defer file.Close()
var fh PcapHeader
err = binary.Read(file, binary.LittleEndian, &fh)
if err != nil {
os.Exit(1)
}
if fh.MagicNumber != 0xa1b2c3d4 {
os.Exit(1)
}
var pktNum uint32 = 0
for {
// Enregistre la position avant lecture
pos, err := file.Seek(0, os.SEEK_CUR)
if err != nil {
break
}
var ph PacketHeader
err = binary.Read(file, binary.LittleEndian, &ph)
if err != nil {
break
}
// Revenir en arrière pour réécrire
_, err = file.Seek(pos, os.SEEK_SET)
if err != nil {
break
}
pktNum++
ph.TsUsec = pktNum
err = binary.Write(file, binary.LittleEndian, &ph)
if err != nil {
break
}
// Aller au prochain en-tête
_, err = file.Seek(int64(ph.InclLen), os.SEEK_CUR)
if err != nil {
break
}
}
fmt.Printf("fichier %s modifié. %d paquets écrits\n", filename, pktNum)
}
#!/usr/bin/env python3
import sys
import struct
import os
PCAP_HEADER_FMT = "IHHIIII"
PACKET_HEADER_FMT = "IIII"
PCAP_HEADER_SIZE = struct.calcsize(PCAP_HEADER_FMT)
PACKET_HEADER_SIZE = struct.calcsize(PACKET_HEADER_FMT)
def main():
if len(sys.argv) != 2:
sys.exit(1)
file_path = sys.argv[1]
try:
with open(file_path, "r+b") as f:
# Lire l'entête global du fichier pcap
header_data = f.read(PCAP_HEADER_SIZE)
if len(header_data) != PCAP_HEADER_SIZE:
sys.exit(1)
pcap_header = struct.unpack(PCAP_HEADER_FMT, header_data)
magic_number = pcap_header[0]
if magic_number != 0xA1B2C3D4:
sys.exit(1)
pkt_num = 0
while True:
pos = f.tell()
packet_header_data = f.read(PACKET_HEADER_SIZE)
if len(packet_header_data) != PACKET_HEADER_SIZE:
break
ts_sec, ts_usec, incl_len, orig_len = struct.unpack(PACKET_HEADER_FMT, packet_header_data)
# Revenir en arrière pour réécrire l'entête modifiée
f.seek(pos)
pkt_num += 1
new_packet_header = struct.pack(PACKET_HEADER_FMT, ts_sec, pkt_num, incl_len, orig_len)
f.write(new_packet_header)
# Passer au paquet suivant
f.seek(incl_len, os.SEEK_CUR)
print(f"fichier {file_path} modifié. {pkt_num} paquets écrits")
except IOError:
sys.exit(1)
if __name__ == "__main__":
main()
use std::env;
use std::fs::OpenOptions;
use std::io::{self, Read, Seek, SeekFrom, Write};
use std::mem::size_of;
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
struct PcapHeader {
magic_number: u32,
version_major: u16,
version_minor: u16,
thiszone: i32,
sigfigs: u32,
snaplen: u32,
network: u32,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
struct PacketHeader {
ts_sec: u32,
ts_usec: u32,
incl_len: u32,
orig_len: u32,
}
/// Lire un bloc binaire comme une struct
fn read_struct<T: Copy>(buf: &[u8]) -> T {
assert!(buf.len() >= size_of::<T>());
unsafe { *(buf.as_ptr() as *const T) }
}
/// Convertir une struct en Vec<u8> pour écriture
fn write_struct<T: Copy>(val: &T) -> Vec<u8> {
let size = size_of::<T>();
let mut buf = vec![0u8; size];
unsafe {
std::ptr::copy_nonoverlapping(val as *const T as *const u8, buf.as_mut_ptr(), size);
}
buf
}
fn main() -> io::Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} <fichier.pcap>", args[0]);
std::process::exit(1);
}
let path = &args[1];
let mut file = OpenOptions::new().read(true).write(true).open(path)?;
// lit l'entête global du fichier pcap
let mut buf = [0u8; size_of::<PcapHeader>()];
file.read_exact(&mut buf)?;
let header: PcapHeader = read_struct(&buf);
let magic = header.magic_number;
if magic != 0xa1b2c3d4 {
eprintln!("Format PCAP non supporté (magic: 0x{:x})", magic);
std::process::exit(1);
}
let mut pkt_num: u32 = 0;
loop {
let pos = file.seek(SeekFrom::Current(0))?;
let mut buf = [0u8; size_of::<PacketHeader>()];
if file.read_exact(&mut buf).is_err() {
break; // fin du fichier ou erreur
}
let mut ph: PacketHeader = read_struct(&buf);
pkt_num += 1;
ph.ts_usec = pkt_num;
// Retour au début du header pour réécriture
file.seek(SeekFrom::Start(pos))?;
let out = write_struct(&ph);
file.write_all(&out)?;
// saute le contenu pour passer au paquet suivant
if file.seek(SeekFrom::Current(ph.incl_len as i64)).is_err() {
break; // capture incomplète
}
}
println!("fichier {} modifié. {} paquets écrits", path, pkt_num);
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment