作者:grkvl
项目:weav
func fragment(eth layers.Ethernet, ip layers.IPv4, pmtu int, frame *ForwardedFrame, forward func(*ForwardedFrame)) error {
// We are not doing any sort of NAT, so we don't need to worry
// about checksums of IP payload (eg UDP checksum).
headerSize := int(ip.IHL) * 4
// &^ is bit clear (AND NOT). So here we're clearing the lowest 3
// bits.
maxSegmentSize := (pmtu - headerSize) &^ 7
opts := gopacket.SerializeOptions{
FixLengths: false,
ComputeChecksums: true}
payloadSize := int(ip.Length) - headerSize
payload := ip.BaseLayer.Payload[:payloadSize]
offsetBase := int(ip.FragOffset) << 3
origFlags := ip.Flags
ip.Flags = ip.Flags | layers.IPv4MoreFragments
ip.Length = uint16(headerSize + maxSegmentSize)
if eth.EthernetType == layers.EthernetTypeLLC {
// using LLC, so must set eth length correctly. eth length
// is just the length of the payload
eth.Length = ip.Length
} else {
eth.Length = 0
}
for offset := 0; offset < payloadSize; offset += maxSegmentSize {
var segmentPayload []byte
if len(payload) <= maxSegmentSize {
// last one
segmentPayload = payload
ip.Length = uint16(len(payload) + headerSize)
ip.Flags = origFlags
if eth.EthernetType == layers.EthernetTypeLLC {
eth.Length = ip.Length
} else {
eth.Length = 0
}
} else {
segmentPayload = payload[:maxSegmentSize]
payload = payload[maxSegmentSize:]
}
ip.FragOffset = uint16((offset + offsetBase) >> 3)
buf := gopacket.NewSerializeBuffer()
segPayload := gopacket.Payload(segmentPayload)
err := gopacket.SerializeLayers(buf, opts, ð, &ip, &segPayload)
if err != nil {
return err
}
// make copies of the frame we received
segFrame := *frame
segFrame.frame = buf.Bytes()
forward(&segFrame)
}
return nil
}
作者:jcantril
项目:gear
func testSerialization(t *testing.T, p gopacket.Packet, data []byte) {
// Test re-serialization.
slayers := []gopacket.SerializableLayer{}
for _, l := range p.Layers() {
slayers = append(slayers, l.(gopacket.SerializableLayer))
if h, ok := l.(canSetNetLayer); ok {
if err := h.SetNetworkLayerForChecksum(p.NetworkLayer()); err != nil {
t.Fatal("can't set network layer:", err)
}
}
}
for _, opts := range []gopacket.SerializeOptions{
gopacket.SerializeOptions{},
gopacket.SerializeOptions{FixLengths: true},
gopacket.SerializeOptions{ComputeChecksums: true},
gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true},
} {
buf := gopacket.NewSerializeBuffer()
err := gopacket.SerializeLayers(buf, opts, slayers...)
if err != nil {
t.Errorf("unable to reserialize layers with opts %#v: %v", opts, err)
} else if !bytes.Equal(buf.Bytes(), data) {
t.Errorf("serialization failure with opts %#v:\n---want---\n%v\n---got---\n%v\nBASH-colorized diff, want->got:\n%v", opts, hex.Dump(data), hex.Dump(buf.Bytes()), diffString(data, buf.Bytes()))
}
}
}
作者:grkvl
项目:weav
func (dec *EthernetDecoder) sendICMPFragNeeded(mtu int, sendFrame func([]byte) error) error {
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true}
ipHeaderSize := int(dec.ip.IHL) * 4 // IHL is the number of 32-byte words in the header
payload := gopacket.Payload(dec.ip.BaseLayer.Contents[:ipHeaderSize+8])
err := gopacket.SerializeLayers(buf, opts,
&layers.Ethernet{
SrcMAC: dec.eth.DstMAC,
DstMAC: dec.eth.SrcMAC,
EthernetType: dec.eth.EthernetType},
&layers.IPv4{
Version: 4,
TOS: dec.ip.TOS,
Id: 0,
Flags: 0,
FragOffset: 0,
TTL: 64,
Protocol: layers.IPProtocolICMPv4,
DstIP: dec.ip.SrcIP,
SrcIP: dec.ip.DstIP},
&layers.ICMPv4{
TypeCode: 0x304,
Id: 0,
Seq: uint16(mtu)},
&payload)
if err != nil {
return err
}
log.Printf("Sending ICMP 3,4 (%v -> %v): PMTU= %v\n", dec.ip.DstIP, dec.ip.SrcIP, mtu)
return sendFrame(buf.Bytes())
}
作者:adie
项目:weav
func (dec *EthernetDecoder) formICMPMTUPacket(mtu int) ([]byte, error) {
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true}
ipHeaderSize := int(dec.ip.IHL) * 4 // IHL is the number of 32-byte words in the header
payload := gopacket.Payload(dec.ip.BaseLayer.Contents[:ipHeaderSize+8])
err := gopacket.SerializeLayers(buf, opts,
&layers.Ethernet{
SrcMAC: dec.eth.DstMAC,
DstMAC: dec.eth.SrcMAC,
EthernetType: dec.eth.EthernetType},
&layers.IPv4{
Version: 4,
TOS: dec.ip.TOS,
Id: 0,
Flags: 0,
FragOffset: 0,
TTL: 64,
Protocol: layers.IPProtocolICMPv4,
DstIP: dec.ip.SrcIP,
SrcIP: dec.ip.DstIP},
&layers.ICMPv4{
TypeCode: 0x304,
Id: 0,
Seq: uint16(mtu)},
&payload)
if err != nil {
return []byte{}, err
}
return buf.Bytes(), nil
}
作者:jcantril
项目:gear
// writeARP writes an ARP request for each address on our local network to the
// pcap handle.
func writeARP(handle *pcap.Handle, iface *net.Interface, addr *net.IPNet) error {
// Set up all the layers' fields we can.
eth := layers.Ethernet{
SrcMAC: iface.HardwareAddr,
DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
EthernetType: layers.EthernetTypeARP,
}
arp := layers.ARP{
AddrType: layers.LinkTypeEthernet,
Protocol: layers.EthernetTypeIPv4,
HwAddressSize: 6,
ProtAddressSize: 4,
Operation: layers.ARPRequest,
SourceHwAddress: []byte(iface.HardwareAddr),
SourceProtAddress: []byte(addr.IP),
DstHwAddress: []byte{0, 0, 0, 0, 0, 0},
}
// Set up buffer and options for serialization.
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
// Send one packet for every address.
for ip := range ips(addr) {
arp.DstProtAddress = []byte(ip)
gopacket.SerializeLayers(buf, opts, ð, &arp)
if err := handle.WritePacketData(buf.Bytes()); err != nil {
return err
}
}
return nil
}
作者:pombredann
项目:gear
// newScanner creates a new scanner for a given destination IP address, using
// router to determine how to route packets to that IP.
func newScanner(ip net.IP, router routing.Router) (*scanner, error) {
s := &scanner{
dst: ip,
opts: gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
},
buf: gopacket.NewSerializeBuffer(),
}
// Figure out the route to the IP.
iface, gw, src, err := router.Route(ip)
if err != nil {
return nil, err
}
log.Printf("scanning ip %v with interface %v, gateway %v, src %v", ip, iface.Name, gw, src)
s.gw, s.src, s.iface = gw, src, iface
// Open the handle for reading/writing.
// Note we could very easily add some BPF filtering here to greatly
// decrease the number of packets we have to look at when getting back
// scan results.
handle, err := pcap.OpenLive(iface.Name, 65536, true, time.Millisecond)
if err != nil {
return nil, err
}
s.handle = handle
return s, nil
}
作者:jcantril
项目:gear
func BenchmarkSerializeTcpFixLengthsComputeChecksums(b *testing.B) {
slayers := getSerializeLayers()
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{FixLengths: true, ComputeChecksums: true}
for i := 0; i < b.N; i++ {
gopacket.SerializeLayers(buf, opts, slayers...)
}
}
作者:jcantril
项目:gear
func BenchmarkSerializeTcpNoOptions(b *testing.B) {
slayers := getSerializeLayers()
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{}
for i := 0; i < b.N; i++ {
gopacket.SerializeLayers(buf, opts, slayers...)
}
}
作者:ThomasJClar
项目:cs4404projec
/*Serialize helps to serialize an IPv4 packet that has been tampered with.
The IP checksum is recomputed, and the whole packet is concatenated together
into a byte slice that can be passed to netfilter.*/
func Serialize(ipLayer *layers.IPv4) ([]byte, error) {
/*Write the IPv4 header into a gopacket buffer*/
buf := gopacket.NewSerializeBuffer()
err := ipLayer.SerializeTo(buf, gopacket.SerializeOptions{FixLengths: false, ComputeChecksums: true})
if err != nil {
return nil, err
}
/*Write the gopacket buffer and the payload into a byte buffer, concatenating
the entire packet together.*/
var buf2 bytes.Buffer
buf2.Write(buf.Bytes())
buf2.Write(ipLayer.Payload)
return buf2.Bytes(), nil
}
作者:postfi
项目:rout
func UpdatePkt(p *Packet) {
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
ComputeChecksums: true,
FixLengths: true,
}
if len(p.app) > 0 {
appbuf, _ := buf.PrependBytes(len(p.app))
copy(appbuf, p.app)
}
if p.tcp != nil {
p.tcp.SetNetworkLayerForChecksum(p.ip)
p.tcp.SerializeTo(buf, opts)
} else {
p.udp.SetNetworkLayerForChecksum(p.ip)
p.udp.SerializeTo(buf, opts)
}
p.ip.SerializeTo(buf, opts)
p.eth.SerializeTo(buf, opts)
p.data = buf.Bytes()
}
作者:adie
项目:weav
func NewRawUDPSender(conn *LocalConnection) (*RawUDPSender, error) {
ipSocket, err := dialIP(conn)
if err != nil {
return nil, err
}
udpHeader := &layers.UDP{SrcPort: layers.UDPPort(Port)}
ipBuf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths: true,
// UDP header is calculated with a phantom IP
// header. Yes, it's totally nuts. Thankfully, for UDP
// over IPv4, the checksum is optional. It's not
// optional for IPv6, but we'll ignore that for
// now. TODO
ComputeChecksums: false}
return &RawUDPSender{
ipBuf: ipBuf,
opts: opts,
udpHeader: udpHeader,
socket: ipSocket,
conn: conn}, nil
}
作者:aerobles
项目:IPSecDiagTool-Applicatio
//sendPacket generates & sends a packet of arbitrary size to a specific destination.
//The size specified should be larger then 40bytes.
func sendPacket(sourceIP string, destinationIP string, size int, message string, appID int, chanID int, icmpType layers.ICMPv4TypeCode) []byte {
var payloadSize int
if size < 28 {
//Unable to create smaller packets.
payloadSize = 0
} else {
payloadSize = size - 28
}
//Convert IP to 4bit representation
srcIP := net.ParseIP(sourceIP).To4()
dstIP := net.ParseIP(destinationIP).To4()
//IP Layer
ip := layers.IPv4{
SrcIP: srcIP,
DstIP: dstIP,
Version: 4,
TTL: 64,
Protocol: layers.IPProtocolICMPv4,
}
icmp := layers.ICMPv4{
TypeCode: icmpType,
}
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
ipHeaderBuf := gopacket.NewSerializeBuffer()
err := ip.SerializeTo(ipHeaderBuf, opts)
if err != nil {
panic(err)
}
//Set "Don't Fragment"-Flag in Header
ipHeader, err := ipv4.ParseHeader(ipHeaderBuf.Bytes())
ipHeader.Flags |= ipv4.DontFragment
if err != nil {
panic(err)
}
payloadBuf := gopacket.NewSerializeBuffer()
//Influence the payload size
payload := gopacket.Payload(generatePayload(payloadSize, ","+strconv.Itoa(appID)+","+strconv.Itoa(chanID)+","+message+","))
err = gopacket.SerializeLayers(payloadBuf, opts, &icmp, payload)
if err != nil {
panic(err)
}
//Send packet
var packetConn net.PacketConn
var rawConn *ipv4.RawConn
packetConn, err = net.ListenPacket("ip4:icmp", srcIP.String())
if err != nil {
panic(err)
}
rawConn, err = ipv4.NewRawConn(packetConn)
if err != nil {
panic(err)
}
err = rawConn.WriteTo(ipHeader, payloadBuf.Bytes(), nil)
return append(ipHeaderBuf.Bytes(), payloadBuf.Bytes()...)
}
作者:postfi
项目:gorawtcpsy
func main() {
flag.Parse()
args := flag.Args()
if len(args) != 2 {
fmt.Printf("Usage: %s <ip> <port>\n", os.Args[0])
os.Exit(-1)
}
// parse the destination host and port from the command line args
dstip := net.ParseIP(args[0]).To4()
dport_, err := strconv.ParseInt(args[1], 10, 16)
if err != nil {
panic(err)
}
dport := layers.TCPPort(dport_)
// get our local ip.
srcip, err := localIP(dstip)
if err != nil {
panic(err)
}
// Our IPv4 header
ip := &layers.IPv4{
Version: 4,
IHL: 5,
TOS: 0,
Length: 0, // FIX
Id: 12345,
FragOffset: 16384,
TTL: 64,
Protocol: layers.IPProtocolTCP,
Checksum: 0,
SrcIP: srcip,
DstIP: dstip,
}
// Our TCP header
tcp := &layers.TCP{
SrcPort: 45677,
DstPort: dport,
Seq: 1105024978,
Ack: 0,
SYN: true,
Window: 14600,
Checksum: 0,
Urgent: 0,
}
tcp.DataOffset = uint8(unsafe.Sizeof(tcp))
tcp.SetNetworkLayerForChecksum(ip)
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
ComputeChecksums: true, // automatically compute checksums
}
err = ip.SerializeTo(buf, opts)
if err != nil {
panic(err)
}
err = tcp.SerializeTo(buf, opts)
if err != nil {
panic(err)
}
conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0")
if err != nil {
panic(err)
}
_, err = conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip})
if err != nil {
panic(err)
}
var b []byte
b = make([]byte, 152)
n, addr, err := conn.ReadFrom(b)
if err != nil {
panic(err)
}
if addr.String() == dstip.String() {
// Decode a packet
packet := gopacket.NewPacket(b[:n], layers.LayerTypeTCP, gopacket.Default)
// Get the TCP layer from this packet
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
//fmt.Printf("SYN: %v, ACK: %v, RST: %v\n", tcp.SYN, tcp.ACK, tcp.RST)
if tcp.SYN && tcp.ACK {
fmt.Printf("Port %d is OPEN\n", dport)
} else {
fmt.Printf("Port %d is CLOSED\n", dport)
}
}
}
}
作者:postfi
项目:gorawtcpsy
// Sends an ARP request packet to determine the MAC address of an IP
func remoteMac(dev string, srcmac net.HardwareAddr, srcip, dstip net.IP) (net.HardwareAddr, error) {
var dstmac net.HardwareAddr
eth := &layers.Ethernet{
SrcMAC: srcmac,
DstMAC: net.HardwareAddr{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
EthernetType: layers.EthernetTypeARP,
}
arp := &layers.ARP{
AddrType: layers.LinkTypeEthernet,
Protocol: layers.EthernetTypeIPv4,
HwAddressSize: 6,
ProtAddressSize: 4,
Operation: 1, //arp request
SourceHwAddress: srcmac,
SourceProtAddress: srcip,
DstHwAddress: net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
DstProtAddress: dstip,
}
buf := gopacket.NewSerializeBuffer()
err := gopacket.SerializeLayers(
buf,
gopacket.SerializeOptions{
ComputeChecksums: true, // automatically compute checksums
FixLengths: true,
},
eth, arp,
)
if err != nil {
return dstmac, err
}
handle, err := pcap.OpenLive(`rpcap://`+dev, 65535, true, time.Second*1)
if err != nil {
return dstmac, err
}
defer handle.Close()
var wg sync.WaitGroup
handle.SetBPFFilter(fmt.Sprintf("arp and ether host %s", srcmac.String()))
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
macchan := make(chan net.HardwareAddr, 1)
wg.Add(1)
go func() {
stop := false
go func() {
<-time.After(time.Second * 2)
stop = true
}()
for {
if stop {
break
}
packet, err := packetSource.NextPacket()
if err == io.EOF {
break
} else if err != nil {
//log.Println("Error:", err)
continue
}
if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil {
arp_, _ := arpLayer.(*layers.ARP)
if bytes.Equal(arp_.SourceProtAddress, dstip) && arp_.Operation == 2 {
macchan <- arp_.SourceHwAddress
break
}
}
}
wg.Done()
}()
err = handle.WritePacketData(buf.Bytes())
if err != nil {
return dstmac, err
}
wg.Wait()
dstmac = <-macchan
return dstmac, nil
}
作者:MDfo
项目:initcwndchec
//Detectinitcwnd attempts to detect the initial congession window of an http endpoint.
//First does a 3 way tcp handshake, sends GET request and then does not ack any response while measuring the packets received. This allows us to see how much data the server can send without acknowledgement.
func Detectinitcwnd(host, url string, dstip net.IP) (pkt_count, payload_size int, fullpayload []byte, err error) {
pldata := []byte(fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", url, host))
var dstport layers.TCPPort
dstport = layers.TCPPort(80)
srcip, sport := localIPPort(dstip)
srcport := layers.TCPPort(sport)
log.Printf("using srcip: %v", srcip.String())
log.Printf("using dstip: %v", dstip.String())
// Our IP header... not used, but necessary for TCP checksumming.
ip := &layers.IPv4{
SrcIP: srcip,
DstIP: dstip,
Protocol: layers.IPProtocolTCP,
}
//layers.TCPOption{3, 3, []byte{7}} maybe for window scaling... dunno
tcpopts := []layers.TCPOption{layers.TCPOption{2, 4, []byte{5, 172}}} //Set MSS 1452
// Our TCP header
tcp := &layers.TCP{
SrcPort: srcport,
DstPort: dstport,
Seq: 1105024978,
SYN: true,
Window: 65535,
Options: tcpopts,
}
tcp.SetNetworkLayerForChecksum(ip)
// Serialize. Note: we only serialize the TCP layer, because the
// socket we get with net.ListenPacket wraps our data in IPv4 packets
// already. We do still need the IP layer to compute checksums
// correctly, though.
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
ComputeChecksums: true,
FixLengths: true,
}
err = gopacket.SerializeLayers(buf, opts, tcp)
if err != nil {
return
}
var out1 bytes.Buffer
iptset := exec.Command("iptables", "-A", "OUTPUT", "-p", "tcp", "--tcp-flags", "RST", "RST", "-s", srcip.String(), "--sport", porttoint(srcport), "--dport", porttoint(dstport), "-j", "DROP")
iptset.Stderr = &out1
log.Println(iptset)
err = iptset.Run()
if err != nil {
return
}
log.Println(out1.String())
iptrem := exec.Command("iptables", "-D", "OUTPUT", "-p", "tcp", "--tcp-flags", "RST", "RST", "-s", srcip.String(), "--sport", porttoint(srcport), "--dport", porttoint(dstport), "-j", "DROP")
conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0")
if err != nil {
return
}
defer func() {
fmt.Println(iptrem)
var out bytes.Buffer
iptrem.Stderr = &out
err = iptrem.Run()
if err != nil {
log.Println(err)
}
fmt.Printf(out.String())
log.Println("Removed iptable rule")
//Now RST should be allowed... send it
rst_pkt := &layers.TCP{
SrcPort: srcport,
DstPort: dstport,
Seq: 1105024980,
Window: 65535,
RST: true,
}
rst_pkt.SetNetworkLayerForChecksum(ip)
if err := gopacket.SerializeLayers(buf, opts, rst_pkt); err != nil {
//Shadowing err since we dont care
log.Println(err)
}
if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil {
//Shadowing err since we dont care
log.Println(err)
}
}()
log.Println("writing request")
_, err = conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip})
if err != nil {
return
}
// Set deadline so we don't wait forever.
err = conn.SetDeadline(time.Now().Add(15 * time.Second))
if err != nil {
return
}
//Capture synack from our syn, return the ack value
//.........这里部分代码省略.........