From d787bce15937e2b9f91c46bcd63956c1604563d8 Mon Sep 17 00:00:00 2001 From: juneflbjpz Date: Fri, 13 Sep 2024 23:27:03 +0800 Subject: [PATCH] first commit --- .gitignore | 4 ++ InitParams.go | 49 ++++++++++++++++++ README.md | 11 ++++ common.go | 42 +++++++++++++++ go.mod | 21 ++++++++ go.sum | 55 ++++++++++++++++++++ iptables.go | 30 +++++++++++ main.go | 89 ++++++++++++++++++++++++++++++++ packet.go | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 441 insertions(+) create mode 100644 .gitignore create mode 100644 InitParams.go create mode 100644 README.md create mode 100644 common.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 iptables.go create mode 100644 main.go create mode 100644 packet.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ab68bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +lagran +.idea +.DS_Store +*.DS_Store diff --git a/InitParams.go b/InitParams.go new file mode 100644 index 0000000..149cde2 --- /dev/null +++ b/InitParams.go @@ -0,0 +1,49 @@ +package main + +import ( + "flag" +) + +var Port string +var SaEnable bool +var WindowSa uint16 +var AEnable bool +var WindowA uint16 +var PaEnable bool +var WindowPa uint16 +var FaEnable bool +var WindowFa uint16 +var Debug bool +var Daemon bool +var Forever bool + +func InitParams() (string, bool, uint16, bool, uint16, bool, uint16, bool, uint16, bool, bool, bool) { + flag.StringVar(&Port, "p", "443", "The port of geneva, multi ports should be like \"80,443\"") + + flag.BoolVar(&SaEnable, "sa", true, "Enable to handle the packet when TCP flag SYN and ACK are 1.") + var wsa int + flag.IntVar(&wsa, "wsa", 4, "The window size of packet when TCP flag SYN and ACK are 1, available only when param -sa is true") + + flag.BoolVar(&AEnable, "a", true, "Enable to handle the packet when TCP flag ACK is 1") + var wa int + flag.IntVar(&wa, "wa", 4, "The window size of packet when TCP flag ACK is 1, available only when param -a is true") + + flag.BoolVar(&PaEnable, "pa", true, "Enable to handle the packet when TCP flag PSH and ACK are 1.") + var wpa int + flag.IntVar(&wpa, "wpa", 4, "The window size of packet when TCP flag PSH and ACK are 1, available only when param -pa is true") + + flag.BoolVar(&FaEnable, "fa", true, "Enable to handle the packet when TCP flag FIN and ACK are 1.") + var wfa int + flag.IntVar(&wfa, "wfa", 4, "The window size of packet when TCP flag FIN and ACK are 1, available only when param -fa is true") + + flag.BoolVar(&Debug, "debug", false, "Debug mode.") + flag.BoolVar(&Daemon, "daemon", false, "Run in daemon") + flag.BoolVar(&Forever, "forever", false, "Run forever") + + flag.Parse() + WindowSa = uint16(wsa) + WindowA = uint16(wa) + WindowPa = uint16(wpa) + WindowFa = uint16(wfa) + return Port, SaEnable, WindowSa, AEnable, WindowA, PaEnable, WindowPa, FaEnable, WindowFa, Debug, Daemon, Forever +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..f15cb88 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +- 本小程序主要用来实现Geneva的以下四条规则,还可以自定义端口、需要修改的window size的值。 +``` +"[TCP:flags:SA]-tamper{TCP:window:replace:0}-|" +"[TCP:flags:A]-tamper{TCP:window:replace:0}-|" +"[TCP:flags:PA]-tamper{TCP:window:replace:0}-|" +"[TCP:flags:FA]-tamper{TCP:window:replace:0}-|" +``` +- 默认四条规则全部开启,具体使用方法参考`./lagran -h`。 +- 例如:开启第一条规则并设置window为2,同时关闭2、3、4条规则 +```./lagran -debug -p 80 -sa=true -wsa 2 -a=false -pa=false -fa=false``` +- 注意:本小程序依赖libpcap-dev、libnetfilter-queue-dev、iptables等使用之前请先安装。 \ No newline at end of file diff --git a/common.go b/common.go new file mode 100644 index 0000000..7c9c8cc --- /dev/null +++ b/common.go @@ -0,0 +1,42 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "strconv" +) + +func getProcessOwner() string { + stdout, err := exec.Command("ps", "-o", "user=", "-p", strconv.Itoa(os.Getpid())).Output() + if err != nil { + log.Fatalln(err) + } + return string(stdout) +} + +func StripSlice(slice []string, element string) []string { + for i := 0; i < len(slice); { + if slice[i] == element && i != len(slice)-1 { + slice = append(slice[:i], slice[i+1:]...) + } else if slice[i] == element && i == len(slice)-1 { + slice = slice[:i] + } else { + i++ + } + } + return slice +} + +func SubProcess(args []string) *exec.Cmd { + cmd := exec.Command(args[0], args[1:]...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Start() + if err != nil { + fmt.Fprintf(os.Stderr, "[-] Error: %s\n", err) + } + return cmd +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..aa2da59 --- /dev/null +++ b/go.mod @@ -0,0 +1,21 @@ +module lagran + +go 1.18 + +require ( + github.com/coreos/go-iptables v0.6.0 + github.com/florianl/go-nfqueue v1.3.1 + github.com/google/gopacket v1.1.19 + github.com/panjf2000/ants/v2 v2.5.0 +) + +require ( + github.com/google/go-cmp v0.5.7 // indirect + github.com/josharian/native v1.0.0 // indirect + github.com/mdlayher/netlink v1.6.0 // indirect + github.com/mdlayher/socket v0.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7bc05e2 --- /dev/null +++ b/go.sum @@ -0,0 +1,55 @@ +github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/florianl/go-nfqueue v1.3.1 h1:khQ9fYCrjbu5CF8dZF55G2RTIEIQRI0Aj5k3msJR6Gw= +github.com/florianl/go-nfqueue v1.3.1/go.mod h1:aHWbgkhryJxF5XxYvJ3oRZpdD4JP74Zu/hP1zuhja+M= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk= +github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0= +github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA= +github.com/mdlayher/socket v0.1.1 h1:q3uOGirUPfAV2MUoaC7BavjQ154J7+JOkTWyiV+intI= +github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs= +github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q= +github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= diff --git a/iptables.go b/iptables.go new file mode 100644 index 0000000..1fad47a --- /dev/null +++ b/iptables.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "github.com/coreos/go-iptables/iptables" + "os" +) + +func SetIptable(sport string) { + ipt, err := iptables.New() + if err != nil { + fmt.Printf("Iptabels new error:%v", err) + os.Exit(1) + } + _ = ipt.AppendUnique("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "SYN,ACK", "-j", "NFQUEUE", "--queue-balance", "1000:1127") + _ = ipt.AppendUnique("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "ACK", "-j", "NFQUEUE", "--queue-balance", "2000:2127") + _ = ipt.AppendUnique("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "PSH,ACK", "-j", "NFQUEUE", "--queue-balance", "3000:3127") + _ = ipt.AppendUnique("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "FIN,ACK", "-j", "NFQUEUE", "--queue-balance", "4000:4127") +} +func UnsetIptable(sport string) { + ipt, err := iptables.New() + if err != nil { + fmt.Printf("Iptabels new error:%v", err) + os.Exit(1) + } + _ = ipt.Delete("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "SYN,ACK", "-j", "NFQUEUE", "--queue-balance", "1000:1127") + _ = ipt.Delete("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "ACK", "-j", "NFQUEUE", "--queue-balance", "2000:2127") + _ = ipt.Delete("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "PSH,ACK", "-j", "NFQUEUE", "--queue-balance", "3000:3127") + _ = ipt.Delete("filter", "OUTPUT", "-p", "tcp", "-m", "multiport", "--sport", sport, "--tcp-flags", "SYN,RST,ACK,FIN,PSH", "FIN,ACK", "-j", "NFQUEUE", "--queue-balance", "4000:4127") +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..b5de4b3 --- /dev/null +++ b/main.go @@ -0,0 +1,89 @@ +package main + +import ( + "fmt" + "github.com/panjf2000/ants/v2" + "io/ioutil" + "log" + "os" + "sync" +) + +const ( + DAEMON = "daemon" + FOREVER = "forever" +) + +func init() { + if getProcessOwner() != "root\n" { + log.Fatalln("Please run this program with root.") + } +} + +func main() { + InitParams() + if !Debug { + log.SetOutput(ioutil.Discard) + } + if Daemon { + SubProcess(StripSlice(os.Args, "-"+DAEMON)) + fmt.Printf("[*] Daemon running in PID: %d PPID: %d\n", os.Getpid(), os.Getppid()) + os.Exit(0) + } else if Forever { + for { + cmd := SubProcess(StripSlice(os.Args, "-"+FOREVER)) + fmt.Printf("[*] Forever running in PID: %d PPID: %d\n", os.Getpid(), os.Getppid()) + cmd.Wait() + } + os.Exit(0) + } else { + UnsetIptable(Port) + SetIptable(Port) + var wg sync.WaitGroup + p1, _ := ants.NewPoolWithFunc(512, func(i interface{}) { + packetHandle(i.(int)) + wg.Done() + }) + defer p1.Release() + // Submit tasks one by one. + log.Println("Starting Task p1") + for i := 1000; i < 1512; i++ { + wg.Add(1) + _ = p1.Invoke(int(i)) + } + p2, _ := ants.NewPoolWithFunc(1512, func(i interface{}) { + packetHandle(i.(int)) + wg.Done() + }) + defer p2.Release() + // Submit tasks one by one. + log.Println("Starting Task p2") + for i := 2000; i < 2512; i++ { + wg.Add(1) + _ = p2.Invoke(int(i)) + } + p3, _ := ants.NewPoolWithFunc(512, func(i interface{}) { + packetHandle(i.(int)) + wg.Done() + }) + defer p3.Release() + // Submit tasks one by one. + log.Println("Starting Task p3") + for i := 3000; i < 3512; i++ { + wg.Add(1) + _ = p3.Invoke(int(i)) + } + p4, _ := ants.NewPoolWithFunc(512, func(i interface{}) { + packetHandle(i.(int)) + wg.Done() + }) + defer p4.Release() + // Submit tasks one by one. + log.Println("Starting Task p4") + for i := 4000; i < 4512; i++ { + wg.Add(1) + _ = p4.Invoke(int(i)) + } + wg.Wait() + } +} diff --git a/packet.go b/packet.go new file mode 100644 index 0000000..d85d124 --- /dev/null +++ b/packet.go @@ -0,0 +1,140 @@ +package main + +import ( + "context" + "fmt" + "github.com/florianl/go-nfqueue" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "log" + "net" + "regexp" + "strings" + "time" +) + +func packetHandle(queueNum int) { + config := nfqueue.Config{ + NfQueue: uint16(queueNum), + MaxPacketLen: 0xFFFF, + MaxQueueLen: 0xFF, + Copymode: nfqueue.NfQnlCopyPacket, + WriteTimeout: 200 * time.Millisecond, + } + + nf, err := nfqueue.Open(&config) + if err != nil { + fmt.Println("could not open nfqueue socket:", err) + return + } + + defer nf.Close() + + ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + + fn := func(a nfqueue.Attribute) int { + id := *a.PacketID + var srcIP net.IP + var dstIP net.IP + log.Printf("PKT[%03d]\t\n", id) + + packet := gopacket.NewPacket(*a.Payload, layers.LayerTypeIPv4, gopacket.Default) + + // Get the IP layer from this packet + if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil { + // Get actual IP data from this layer + ip, _ := ipLayer.(*layers.IPv4) + srcIP = ip.SrcIP + dstIP = ip.DstIP + log.Printf("%15s > %-15s \n", srcIP, dstIP) + } + if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { + tcp, _ := tcpLayer.(*layers.TCP) + ports := strings.Split(Port, ",") + reg := regexp.MustCompile(`\d+`) + sport := reg.FindString(tcp.SrcPort.String()) + var matchedPort bool = false + + for _, port := range ports { + if port == sport { + matchedPort = true + break + } + } + if matchedPort { + var ok1 bool = SaEnable && tcp.SYN && tcp.ACK + var ok2 bool = AEnable && tcp.ACK && !tcp.PSH && !tcp.FIN && !tcp.SYN && !tcp.RST + var ok3 bool = PaEnable && tcp.PSH && tcp.ACK + var ok4 bool = FaEnable && tcp.FIN && tcp.ACK + var windowSize uint16 + if ok1 || ok2 || ok3 || ok4 { + if ok1 { + windowSize = WindowSa + log.Println("Handle SYN=1 and ACK=1") + } + if ok2 { + windowSize = WindowA + log.Println("Handle ACK=1") + } + if ok3 { + windowSize = WindowPa + log.Println("Handle PSH=1 and ACK=1") + } + if ok4 { + windowSize = WindowFa + log.Println("Handle FIN=1 and ACK=1") + } + packet.TransportLayer().(*layers.TCP).Window = windowSize + err := packet.TransportLayer().(*layers.TCP).SetNetworkLayerForChecksum(packet.NetworkLayer()) + if err != nil { + log.Fatalf("SetNetworkLayerForChecksum error: %v", err) + } + buffer := gopacket.NewSerializeBuffer() + options := gopacket.SerializeOptions{ + ComputeChecksums: true, + FixLengths: true, + } + if err := gopacket.SerializePacket(buffer, options, packet); err != nil { + log.Fatalf("SerializePacket error: %v", err) + } + packetBytes := buffer.Bytes() + log.Printf("Set TCP window size to %d", windowSize) + err = nf.SetVerdictModPacket(id, nfqueue.NfAccept, packetBytes) + if err != nil { + log.Fatalf("SetVerdictModified error: %v", err) + } + return 0 + } + err := nf.SetVerdict(id, nfqueue.NfAccept) + if err != nil { + log.Fatalf("SetVerdictModified error: %v", err) + } + return 0 + } + err := nf.SetVerdict(id, nfqueue.NfAccept) + if err != nil { + log.Fatalf("SetVerdictModified error: %v", err) + } + return 0 + } + err := nf.SetVerdict(id, nfqueue.NfAccept) + if err != nil { + log.Fatalf("SetVerdictModified error: %v", err) + } + return 0 + } + + // Register your function to listen on nflqueue queue 100 + err = nf.RegisterWithErrorFunc(ctx, fn, func(e error) int { + if e != nil { + log.Fatalln("RegisterWithErrorFunc Error:", e) + } + return 0 + }) + if err != nil { + fmt.Println(err) + return + } + <-ctx.Done() +}