前端之家收集整理的这篇文章主要介绍了
Go语言Ubuntu下打印网络请求报文信息,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
package main
import (
"time"
"github.com/google/gopacket/pcap"
"log"
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"strings"
"vprobe/rawtransaction"
"sync"
"encoding/json"
"vprobe/metric"
"strconv"
)
var (
device string = "eth1"
snapshot_len int32 = 1024
promiscuous bool = false
timeout time.Duration = 30 * time.Second
localAddress string
errorNumber int = 0
channel chan bool = make(chan bool)
lock = &sync.RWMutex{}
noresp int = 30000
requestList []rawtransaction.RequestIdentification = make([]rawtransaction.RequestIdentification, 0, 50)
rawTransactions []rawtransaction.Transaction = make([]rawtransaction.Transaction, 50)
transactionList []metric.Transaction = make([]metric.Transaction, 50)
)
func main() {
devices,err := pcap.FindAllDevs()
if err != nil {
log.Fatal(err)
}
MainThread:
for _,dev := range devices {
if strings.EqualFold(dev.Name,device) {
for _,address := range dev.Addresses {
localAddress = address.IP.To4().String()
break MainThread
}
}
}
go capturePacket()
go submitTrans()
go formMetrics()
<-channel
}
func capturePacket() {
handle,err: = pcap.OpenLive(device,snapshot_len,promiscuous,timeout)
if err != nil {
log.Fatal(err)
}
defer handle.Close()
var filter string = "tcp and port 80"
err = handle.SetBPFFilter(filter)
if err != nil {
log.Fatal(err)
}
fmt.Println("Only capturing TCP port 80 packets.")
packetSource := gopacket.NewPacketSource(handle,handle.LinkType())
for packet := range packetSource.Packets() {
printPacketInfo(packet)
}
channel <- true
}
func printPacketInfo(packet gopacket.Packet) {
ipLayer := packet.Layer(layers.LayerTypeIPv4)
if ipLayer != nil {
ip,_ := ipLayer.(*layers.IPv4)
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer != nil {
tcp,_ := tcpLayer.(*layers.TCP)
applicationLayer := packet.ApplicationLayer()
if applicationLayer != nil {
payload := string(applicationLayer.Payload())
if strings.Contains(payload,"HTTP") {
timestamp := int(packet.Metadata().Timestamp.Unix())
lock.Lock()
if strings.EqualFold(localAddress,ip.SrcIP.String()) {
iden := ip.SrcIP.String() + tcp.SrcPort.String() + ip.DstIP.String() + tcp.DstPort.String()
reqiden := rawtransaction.RequestIdentification{
timestamp, -1,iden,false,}
requestList = append(requestList,reqiden)
} else {
iden := ip.DstIP.String() + tcp.DstPort.String() + ip.SrcIP.String() + tcp.SrcPort.String()
for i,_ := range requestList {
if strings.EqualFold(requestList[i].Identification,iden) {
if timestamp - requestList[i].Timestamp > noresp {
} else {
contents := strings.Split(payload," ")
if len(contents) >=2 {
code,err := strconv.Atoi(contents[1])
if err == nil {
requestList[i].Modify = true
requestList[i].RespTimestamp = timestamp
requestList[i].Code = code
} else {
}
}
}
} else {
}
}
}
lock.Unlock()
}
}
}
}
}
func submitTrans() {
c := time.Tick(30 * time.Second)
for _ = range c {
lock.Lock()
tempRequestList := requestList
requestList = requestList[:0]
lock.Unlock()
for _,reqiden := range tempRequestList{
if reqiden.Modify {
rawtra := rawtransaction.Transaction {
rawtransaction.Request{reqiden.Timestamp},rawtransaction.Response{reqiden.RespTimestamp,reqiden.Code},}
rawTransactions = append(rawTransactions,rawtra)
} else {
errorNumber++
}
}
}
}
func formMetrics() {
c := time.Tick(300 * time.Second)
for _ = range c {
for _,rawTransaction := range rawTransactions {
transaction := metric.Transaction{
rawTransaction.Request.Timestamp,rawTransaction.Response.Timestamp - rawTransaction.Request.Timestamp,rawTransaction.Response.Code,}
transactionList = append(transactionList,transaction)
}
metric := metric.Metric{
len(transactionList),transactionList,errorNumber,}
metricJson,_ := json.Marshal(metric)
fmt.Println(string(metricJson))
lock.Lock()
transactionList = transactionList[:0]
rawTransactions = rawTransactions[:0]
errorNumber = 0
lock.Unlock()
}
}