@@ -32,13 +32,17 @@ import (
3232
3333 "github.com/rs/zerolog"
3434 "github.com/shadowy-pycoder/arpspoof"
35+ "github.com/shadowy-pycoder/mshark"
3536 "github.com/shadowy-pycoder/mshark/layers"
37+ "github.com/shadowy-pycoder/mshark/mpcap"
38+ "github.com/shadowy-pycoder/mshark/mpcapng"
3639 "github.com/shadowy-pycoder/mshark/network"
3740 "github.com/shadowy-pycoder/ndpspoof"
3841 "github.com/wzshiming/socks5"
3942)
4043
4144const (
45+ App string = "gohpts"
4246 addrSOCKS string = "127.0.0.1:1080"
4347 addrHTTP string = "127.0.0.1:8080"
4448 readTimeout time.Duration = 30 * time .Second
@@ -120,6 +124,8 @@ type proxyapp struct {
120124 dump strings.Builder
121125 closeConn chan bool
122126 filter * dnsFilter
127+ pcapConf * mshark.Config
128+ pcapW []mshark.PacketWriter
123129
124130 mu sync.RWMutex
125131 availProxyList []ProxyEntry
@@ -531,6 +537,71 @@ func New(conf *Config) (*proxyapp, error) {
531537 return nil , fmt .Errorf ("failed creating ndp spoofer: %v" , err )
532538 }
533539 }
540+ // configure packet capture
541+ if conf .Pcap != "" {
542+ if p .iface == nil {
543+ return nil , fmt .Errorf ("failed getting network interface" )
544+ }
545+ pcc , err := mshark .NewConfig (conf .Pcap )
546+ if err != nil {
547+ return nil , fmt .Errorf ("failed configuring packet capture: %v" , err )
548+ }
549+ pcc .Device = p .iface
550+ pcc .Promisc = true
551+ for _ , ext := range pcc .Exts {
552+ switch ext {
553+ case "txt" :
554+ f , err := createPcapFile (App , ext )
555+ if err != nil {
556+ return nil , err
557+ }
558+ w := mshark .NewWriter (f , true )
559+ if err := w .WriteHeader (pcc ); err != nil {
560+ w .Close ()
561+ return nil , err
562+ }
563+ p .pcapW = append (p .pcapW , w )
564+ case "pcap" :
565+ f , err := createPcapFile (App , ext )
566+ if err != nil {
567+ return nil , err
568+ }
569+ w := mpcap .NewWriter (f )
570+ if err := w .WriteHeader (pcc .Snaplen ); err != nil {
571+ w .Close ()
572+ return nil , err
573+ }
574+ p .pcapW = append (p .pcapW , w )
575+ case "pcapng" :
576+ f , err := createPcapFile (App , ext )
577+ if err != nil {
578+ return nil , err
579+ }
580+ w := mpcapng .NewWriter (f )
581+ if err := w .WriteHeader (App , pcc .Device , pcc .Expr , pcc .Snaplen ); err != nil {
582+ w .Close ()
583+ return nil , err
584+ }
585+ p .pcapW = append (p .pcapW , w )
586+ default :
587+ return nil , fmt .Errorf ("unsupported file format: %s" , ext )
588+ }
589+ }
590+ if len (p .pcapW ) == 0 {
591+ f , err := createPcapFile (App , "pcapng" )
592+ if err != nil {
593+ return nil , err
594+ }
595+ defer f .Close ()
596+ w := mpcapng .NewWriter (f )
597+ if err := w .WriteHeader (App , pcc .Device , pcc .Expr , pcc .Snaplen ); err != nil {
598+ return nil , err
599+ }
600+ p .pcapW = append (p .pcapW , w )
601+
602+ }
603+ p .pcapConf = pcc
604+ }
534605 // configuring DNS
535606 if p .arpspoofer != nil {
536607 gw := p .arpspoofer .GatewayIP ()
@@ -618,6 +689,15 @@ func (p *proxyapp) Run() {
618689 if p .ndpspoofer != nil {
619690 go p .ndpspoofer .Start ()
620691 }
692+
693+ var pcapWg sync.WaitGroup
694+ if p .pcapConf != nil {
695+ pcapWg .Go (func () {
696+ if err := mshark .OpenLive (p .pcapConf , p .pcapW ... ); err != nil {
697+ p .logger .Error ().Err (err ).Msg ("Failed capturing packets" )
698+ }
699+ })
700+ }
621701 tproxyEnabled := p .tproxyAddr != ""
622702 tproxyServers := make ([]* tproxyServer , p .tproxyWorkers )
623703 opts := make (map [string ]string , 20 )
@@ -668,6 +748,10 @@ func (p *proxyapp) Run() {
668748 p .logger .Error ().Err (err ).Msg ("Failed stopping ndp spoofer" )
669749 }
670750 }
751+ if p .pcapConf != nil {
752+ p .logger .Info ().Msg ("Shutting down packet capture.." )
753+ pcapWg .Wait ()
754+ }
671755 close (p .closeConn )
672756 var wg sync.WaitGroup
673757 if tproxyEnabled {
@@ -762,6 +846,10 @@ func (p *proxyapp) Run() {
762846 p .logger .Error ().Err (err ).Msg ("Failed stopping ndp spoofer" )
763847 }
764848 }
849+ if p .pcapConf != nil {
850+ p .logger .Info ().Msg ("Shutting down packet capture.." )
851+ pcapWg .Wait ()
852+ }
765853 close (p .closeConn )
766854 var wg sync.WaitGroup
767855 if tproxyEnabled {
@@ -855,7 +943,11 @@ func (p *proxyapp) getResolver() *net.UDPAddr {
855943 if r .IsLinkLocalUnicast () {
856944 zone = p .iface .Name
857945 }
858- return & net.UDPAddr {IP : net .ParseIP (r .String ()), Port : 53 , Zone : zone }
946+ ip := net .ParseIP (r .String ())
947+ if ip == nil {
948+ continue
949+ }
950+ return & net.UDPAddr {IP : ip , Port : 53 , Zone : zone }
859951 }
860952 }
861953 }
0 commit comments