Skip to content

Commit

Permalink
renamed to main.go
Browse files Browse the repository at this point in the history
  • Loading branch information
[Dirk] committed Aug 6, 2020
1 parent ee21097 commit 4ac41b0
Showing 1 changed file with 215 additions and 0 deletions.
215 changes: 215 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
// Copyright 2017 github.com/DirkDuesentrieb
// license that can be found in the LICENSE file.

// a converter for FortiGate session logs to pcap files
package main

import (
"bufio"
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
"time"
)

const (
globalHeader string = "d4c3b2a1020004000000000000000000ee05000001000000"
info string = `fgsniffer [-fixvpn]
Convert text captures to pcap files.
On the fortigate run
diagnose sniffer packet <interface> '<filter>' <3|6> <count> a
to create a parsable dump.
-fixvpn adds virtual MAC addresses to avoid unparsable dumps on VPN/tunnel interfaces.`
unsafe string = "[]{}/\\*"
)

type (
pcaps struct {
pcap map[string]int
}
packet struct {
data string // raw hex data
size int64
secs, ms int64 // the packets timestamp
port string // the network port (verbose=6)
}
)

var fixvpn bool

func main() {
var scanner *bufio.Scanner
var p packet
now := time.Now()
fname := os.Args[1]
if len(os.Args) > 1 {

switch os.Args[1] {
case "-?", "-h":
fmt.Println(info)
os.Exit(0)
case "-fixvpn":
fixvpn = true
fname = os.Args[2]
fallthrough
default:
f, err := os.Open(fname)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
scanner = bufio.NewScanner(f)
}
} else {
scanner = bufio.NewScanner(os.Stdin)
}
hexLine := regexp.MustCompile("^0x([0-9a-f]+)[ |\t]+(.*$)")
// absolute time
headLineA := regexp.MustCompile("^([0-9-]+ [0-9][0-9]:[0-9][0-9]:[0-9][0-9])\\.([0-9]+) .*$")
// relative time
headLineR := regexp.MustCompile("^([0-9]+)\\.([0-9]+) .*$")
// verbose mode 6
headLine6 := regexp.MustCompile("\\.[0-9]+ ([^ ]+) (in|out|--) ")

pcps := pcaps{make(map[string]int)}

for scanner.Scan() {
date := ""
mseconds := ""
iface := ""
match := false
line := scanner.Text()
hexData := hexLine.FindStringSubmatch(line)

// packet header with absolute time
header := headLineA.FindStringSubmatch(line)
if len(header) == 3 {
match = true
date = header[1]
mseconds = header[2]
}
// packet header with relative time
header = headLineR.FindStringSubmatch(line)
if len(header) == 3 {
match = true
sec, err := time.ParseDuration(header[1] + "s")
if err != nil {
fmt.Println("time.ParseDuration("+header[1]+")", err)
}
date = now.Add(sec).In(time.UTC).Format("2006-01-02 15:04:05")
mseconds = header[2]
}
// verbose mode 6
header = headLine6.FindStringSubmatch(line)
if match && len(header) == 3 {
iface = header[1]
}
if match {
pcps.addPacket(p)
p = newPacket(date, mseconds, iface)
if fixvpn {
p.addData("00090f09010100090f0902020800")
}
}

// packet hex data
if len(hexData) == 3 {
p.addData(strings.Replace(hexData[2][:39], " ", "", -1))
}
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
// clean up
pcps.addPacket(p)
for name, packets := range pcps.pcap {
fmt.Println("created output file", name, "with", packets, "packets.")
}
}

// create file, add global header
func (pcps *pcaps) newPcap(name string) (err error) {
err = ioutil.WriteFile(name, nil, 0644)
if err != nil {
fmt.Println(err)
}
err = appendStringToFile(name, globalHeader)
if err != nil {
fmt.Println(err)
}
return err
}

// create a new packet. We need some data from the header
func newPacket(date, mseconds, iface string) packet {
t, _ := time.Parse("2006-01-02 15:04:05", date)
ms, _ := strconv.ParseInt(mseconds, 10, 64)
return packet{"", 0, t.Unix(), ms, iface}
}

// add a data line to the packet
func (p *packet) addData(data string) {
p.size += int64(len(data) / 2)
p.data += data
}

// all hex lines complete, write the packet to the pcap
func (pcps *pcaps) addPacket(p packet) {
if p.size == 0 {
return
}
fname := "fgsniffer"
if p.port != "" {
for i := 0; i < len(unsafe); i++ {
p.port = strings.Replace(p.port, string(unsafe[i]), "_", -1)
}
fname += "-" + p.port
}
fname += ".pcap"
_, found := pcps.pcap[fname]
if !found {
pcps.pcap[fname] = 0
_ = pcps.newPcap(fname)
}
header := switchEndian(p.secs) + switchEndian(p.ms) + switchEndian(p.size) + switchEndian(p.size)
err := appendStringToFile(fname, header+p.data)
if err != nil {
fmt.Println(err)
}
pcps.pcap[fname]++
}

// 11259375 -> 00abcdef -> efcdab00
func switchEndian(n int64) (r string) {
b := fmt.Sprintf("%08x", n)
for i := 0; i < 4; i++ {
start := 6 - 2*i
r = r + b[start:start+2]
}
return
}

// convert the hex data in string to binary and write it to file
func appendStringToFile(file, text string) error {
f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
return err
}
defer f.Close()
src := []byte(text)
dst := make([]byte, hex.DecodedLen(len(src)))
_, err = hex.Decode(dst, src)
if err != nil {
return err
}
_, err = f.Write(dst)
if err != nil {
return err
}
return nil
}

0 comments on commit 4ac41b0

Please sign in to comment.