예제 #1
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestUnpackOptions(t *testing.T) {
	var p tcp.Packet

	var b packet.Buffer
	b.Init(test_options)

	err := p.Unpack(&b)
	if err != nil {
		t.Fatalf("Error unpacking: %s", err)
	}

	if len(p.Options) != 4 {
		t.Fatalf("Options number mismatch: %d", len(p.Options))
	}

	if p.Options[0].Type != tcp.MSS {
		t.Fatalf("Option MSS mismatch: %x", p.Options[0].Data)
	}

	if p.Options[1].Type != tcp.SAckOk {
		t.Fatalf("Option SAckOk mismatch: %x", p.Options[1].Data)
	}

	if p.Options[2].Type != tcp.Timestamp {
		t.Fatalf("Option Timestamp mismatch: %x", p.Options[2].Data)
	}

	if p.Options[3].Type != tcp.WindowScale {
		t.Fatalf("Option WindowScale mismatch: %x", p.Options[3].Data)
	}
}
예제 #2
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func BenchmarkUnpack(bn *testing.B) {
	var p eth.Packet
	var b packet.Buffer

	for n := 0; n < bn.N; n++ {
		b.Init(test_simple)
		p.Unpack(&b)
	}
}
예제 #3
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func BenchmarkPack(bn *testing.B) {
	var b packet.Buffer
	b.Init(make([]byte, len(test_simple)))

	p := MakeTestSimple()

	for n := 0; n < bn.N; n++ {
		p.Pack(&b)
	}
}
예제 #4
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	tci := uint16(p.Priority)<<13 | p.VLAN
	if p.DropEligible {
		tci |= 0x10
	}

	buf.WriteN(tci)
	buf.WriteN(p.Type)

	return nil
}
예제 #5
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	var tci uint16
	buf.ReadN(&tci)

	p.Priority = (uint8(tci>>8) & 0xE0) >> 5
	p.DropEligible = uint8(tci)&0x10 != 0
	p.VLAN = tci & 0x0FFF

	buf.ReadN(&p.Type)

	return nil
}
예제 #6
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(byte(p.Type))
	buf.WriteN(byte(p.Code))
	buf.WriteN(uint16(0x00))
	buf.WriteN(p.Body)

	if p.csum_seed != 0 {
		p.Checksum = ipv4.CalculateChecksum(buf.LayerBytes(), p.csum_seed)
		buf.PutUint16N(2, p.Checksum)
	}

	return nil
}
예제 #7
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	p.DstAddr = net.HardwareAddr(buf.Next(6))
	p.SrcAddr = net.HardwareAddr(buf.Next(6))

	buf.ReadN(&p.Type)

	if p.Type < 0x0600 {
		p.Length = uint16(p.Type)
		p.Type = LLC
	}

	return nil
}
예제 #8
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(p.Type)
	buf.WriteN(p.AddrType)
	buf.WriteN(p.AddrLen)
	buf.WriteN(p.SrcAddr)

	for i := 0; i < 8-int(p.AddrLen); i++ {
		buf.WriteN(uint8(0x00))
	}

	buf.WriteN(p.EtherType)

	return nil
}
예제 #9
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	buf.ReadN(&p.DSAP)
	buf.ReadN(&p.SSAP)

	if buf.Bytes()[:1][0]&0x1 == 0 ||
		buf.Bytes()[:1][0]&0x3 == 0x1 {
		buf.ReadN(&p.Control)
	} else {
		var ctrl uint8
		buf.ReadN(&ctrl)
		p.Control = uint16(ctrl)
	}

	return nil
}
예제 #10
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestUnpack(t *testing.T) {
	var p eth.Packet

	cmp := MakeTestSimple()

	var b packet.Buffer
	b.Init(test_simple)

	err := p.Unpack(&b)
	if err != nil {
		t.Fatalf("Error unpacking: %s", err)
	}

	if !p.Equals(cmp) {
		t.Fatalf("Packet mismatch:\n%s\n%s", &p, cmp)
	}
}
예제 #11
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestPackWithIPv4(t *testing.T) {
	var b packet.Buffer
	b.Init(make([]byte, len(test_with_ipv4)))

	ip4 := ipv4.Make()
	ip4.SrcAddr = net.ParseIP(ipsrc_str)
	ip4.DstAddr = net.ParseIP(ipdst_str)

	udp := &udp.Packet{
		SrcPort: 52134,
		DstPort: 80,
		Length:  18,
	}

	ip4.SetPayload(udp)

	err := udp.Pack(&b)
	if err != nil {
		t.Fatalf("Error packing: %s", err)
	}

	if !bytes.Equal(test_with_ipv4, b.Buffer()) {
		t.Fatalf("Raw packet mismatch: %x", b.Buffer())
	}
}
예제 #12
0
파일: layers.go 프로젝트: kelixin/go.pkt
// Unpack the given byte slice into the packet list supplied. Note that this
// will not check whether the packet types provided match the raw data. If the
// packet types to be decoded are unknown, UnpackAll() should be used instead.
//
// Note that unpacking is done without copying the input slice, which means that
// if the slice is modifed, it may affect the packets that where unpacked from
// it. If you can't guarantee that the data slice won't change, you'll need to
// copy it and pass the copy to Unpack().
func Unpack(buf []byte, pkts ...packet.Packet) (packet.Packet, error) {
	var b packet.Buffer
	b.Init(buf)

	prev_pkt := packet.Packet(nil)

	for _, p := range pkts {
		if b.Len() <= 0 {
			break
		}

		b.NewLayer()

		err := p.Unpack(&b)
		if err != nil {
			return nil, err
		}

		if prev_pkt != nil {
			prev_pkt.SetPayload(p)
		}

		if p.GuessPayloadType() == packet.None {
			break
		}

		prev_pkt = p
	}

	return pkts[0], nil
}
예제 #13
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestUnpackWithIPv6(t *testing.T) {
	var p icmpv6.Packet

	cmp := MakeTestSimple()
	cmp.Checksum = 0x5bed

	var b packet.Buffer
	b.Init(test_with_ipv6)

	err := p.Unpack(&b)
	if err != nil {
		t.Fatalf("Error unpacking: %s", err)
	}

	if !p.Equals(cmp) {
		t.Fatalf("Packet mismatch:\n%s\n%s", &p, cmp)
	}
}
예제 #14
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	buf.ReadN(&p.Type)
	buf.ReadN(&p.Code)
	buf.ReadN(&p.Checksum)
	buf.ReadN(&p.Id)
	buf.ReadN(&p.Seq)

	/* TODO: data */

	return nil
}
예제 #15
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(p.SrcPort)
	buf.WriteN(p.DstPort)
	buf.WriteN(p.Length)

	if p.csum_seed != 0 {
		p.Checksum =
			ipv4.CalculateChecksum(buf.LayerBytes(), p.csum_seed)
	}

	buf.WriteN(p.Checksum)

	return nil
}
예제 #16
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestPackOptions(t *testing.T) {
	var b packet.Buffer
	b.Init(make([]byte, len(test_options)))

	p := MakeTestSimple()

	p.DataOff = 10

	p.Options = append(p.Options,
		tcp.Option{
			Type: tcp.MSS,
			Len:  4,
			Data: []byte{0x05, 0x78},
		},
	)

	p.Options = append(p.Options,
		tcp.Option{
			Type: tcp.SAckOk,
			Len:  2,
		},
	)

	p.Options = append(p.Options,
		tcp.Option{
			Type: tcp.Timestamp,
			Len:  10,
			Data: []byte{0x61, 0x25, 0xE5, 0xB2, 0x00, 0x13, 0x15, 0x66},
		},
	)

	p.Options = append(p.Options,
		tcp.Option{
			Type: tcp.WindowScale,
			Len:  3,
			Data: []byte{0x0A},
		},
	)

	p.Options = append(p.Options,
		tcp.Option{
			Type: tcp.End,
		},
	)

	err := p.Pack(&b)
	if err != nil {
		t.Fatalf("Error packing: %s", err)
	}

	if !bytes.Equal(test_options, b.Buffer()) {
		t.Fatalf("Raw packet mismatch: %x", b.Buffer())
	}
}
예제 #17
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	buf.ReadN(&p.SrcPort)
	buf.ReadN(&p.DstPort)
	buf.ReadN(&p.Length)
	buf.ReadN(&p.Checksum)

	return nil
}
예제 #18
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestPack(t *testing.T) {
	var b packet.Buffer
	b.Init(make([]byte, len(test_simple)))

	p := MakeTestSimple()

	err := p.Pack(&b)
	if err != nil {
		t.Fatalf("Error packing: %s", err)
	}

	if !bytes.Equal(test_simple, b.Buffer()) {
		t.Fatalf("Raw packet mismatch: %x", b.Buffer())
	}
}
예제 #19
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.Write(p.DstAddr)
	buf.Write(p.SrcAddr)

	if p.Type != LLC {
		buf.WriteN(p.Type)
	} else {
		buf.WriteN(p.Length)
	}

	return nil
}
예제 #20
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(p.DSAP)
	buf.WriteN(p.SSAP)

	if p.Control&0x1 == 0 || p.Control&0x3 == 0x1 {
		buf.WriteN(p.Control)
	} else {
		buf.WriteN(uint8(p.Control))
	}

	return nil
}
예제 #21
0
파일: pkt_test.go 프로젝트: kelixin/go.pkt
func TestPackWithIPv6(t *testing.T) {
	var b packet.Buffer
	b.Init(make([]byte, len(test_with_ipv6)))

	ip6 := ipv6.Make()
	ip6.SrcAddr = net.ParseIP(ipsrc_str)
	ip6.DstAddr = net.ParseIP(ipdst_str)

	icmp6 := MakeTestSimple()

	ip6.SetPayload(icmp6)

	err := icmp6.Pack(&b)
	if err != nil {
		t.Fatalf("Error packing: %s", err)
	}

	if !bytes.Equal(test_with_ipv6, b.Buffer()) {
		t.Fatalf("Raw packet mismatch: %x", b.Buffer())
	}
}
예제 #22
0
파일: layers.go 프로젝트: kelixin/go.pkt
// Pack packets into their binary form. This will stack the packets before
// encoding them (see the Compose() method) and also calculate the checksums.
func Pack(pkts ...packet.Packet) ([]byte, error) {
	var buf packet.Buffer

	base_pkt, err := Compose(pkts...)
	if err != nil {
		return nil, err
	}

	tot_len := int(base_pkt.GetLength())

	buf.Init(make([]byte, tot_len))

	for i := len(pkts) - 1; i >= 0; i-- {
		cur_pkt := pkts[i]
		cur_len := int(cur_pkt.GetLength())

		buf.SetOffset(tot_len - cur_len)
		buf.NewLayer()

		err := cur_pkt.Pack(&buf)
		if err != nil {
			return nil, err
		}
	}

	buf.SetOffset(0)

	return buf.Bytes(), nil
}
예제 #23
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	buf.ReadN(&p.SrcPort)
	buf.ReadN(&p.DstPort)
	buf.ReadN(&p.Seq)
	buf.ReadN(&p.Ack)

	var offns uint8
	buf.ReadN(&offns)

	p.DataOff = offns >> 4

	if offns&0x01 != 0 {
		p.Flags |= NS
	}

	var flags uint8
	buf.ReadN(&flags)

	if flags&0x01 != 0 {
		p.Flags |= Fin
	}

	if flags&0x02 != 0 {
		p.Flags |= Syn
	}

	if flags&0x04 != 0 {
		p.Flags |= Rst
	}

	if flags&0x08 != 0 {
		p.Flags |= PSH
	}

	if flags&0x10 != 0 {
		p.Flags |= Ack
	}

	if flags&0x20 != 0 {
		p.Flags |= Urg
	}

	if flags&0x40 != 0 {
		p.Flags |= ECE
	}

	if flags&0x80 != 0 {
		p.Flags |= Cwr
	}

	buf.ReadN(&p.WindowSize)
	buf.ReadN(&p.Checksum)
	buf.ReadN(&p.Urgent)

options:
	for buf.LayerLen() < int(p.DataOff)*4 {
		var opt_type OptType
		buf.ReadN(&opt_type)

		switch opt_type {
		case End: /* end of options */
			break options

		case Nop: /* padding */
			continue

		default:
			opt := Option{Type: opt_type}

			buf.ReadN(&opt.Len)
			opt.Data = buf.Next(int(opt.Len) - 2)

			p.Options = append(p.Options, opt)
		}
	}

	/* remove padding */
	if buf.LayerLen() < int(p.DataOff)*4 {
		buf.Next(int(p.DataOff)*4 - buf.LayerLen())
	}

	return nil
}
예제 #24
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN((p.Version << 4) | p.IHL)
	buf.WriteN(p.TOS)
	buf.WriteN(p.Length)
	buf.WriteN(p.Id)
	buf.WriteN((uint16(p.Flags) << 13) | p.FragOff)
	buf.WriteN(p.TTL)
	buf.WriteN(p.Protocol)
	buf.WriteN(uint16(0x00))
	buf.Write(p.SrcAddr.To4())
	buf.Write(p.DstAddr.To4())

	p.checksum(buf.LayerBytes()[:20])
	buf.PutUint16N(10, p.Checksum)

	return nil
}
예제 #25
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(p.HWType)
	buf.WriteN(p.ProtoType)

	buf.WriteN(p.HWAddrLen)
	buf.WriteN(p.ProtoAddrLen)

	buf.WriteN(p.Operation)

	buf.Write(p.HWSrcAddr[len(p.HWSrcAddr)-int(p.HWAddrLen):])
	buf.Write(p.ProtoSrcAddr[len(p.ProtoSrcAddr)-int(p.ProtoAddrLen):])

	buf.Write(p.HWDstAddr[len(p.HWDstAddr)-int(p.HWAddrLen):])
	buf.Write(p.ProtoDstAddr[len(p.ProtoDstAddr)-int(p.ProtoAddrLen):])

	return nil
}
예제 #26
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	buf.ReadN(&p.OUI)
	buf.ReadN(&p.Type)

	return nil
}
예제 #27
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(p.OUI)
	buf.WriteN(p.Type)

	return nil
}
예제 #28
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Unpack(buf *packet.Buffer) error {
	var versihl uint8
	buf.ReadN(&versihl)

	p.Version = versihl >> 4
	p.IHL = versihl & 0x0F

	buf.ReadN(&p.TOS)
	buf.ReadN(&p.Length)
	buf.ReadN(&p.Id)

	var flagsfrag uint16
	buf.ReadN(&flagsfrag)
	p.Flags = Flags(flagsfrag >> 13)
	p.FragOff = flagsfrag & 0x1FFF

	buf.ReadN(&p.TTL)

	buf.ReadN(&p.Protocol)

	buf.ReadN(&p.Checksum)

	p.SrcAddr = net.IP(buf.Next(4))
	p.DstAddr = net.IP(buf.Next(4))

	/* TODO: Options */

	return nil
}
예제 #29
0
파일: pkt.go 프로젝트: kelixin/go.pkt
func (p *Packet) Pack(buf *packet.Buffer) error {
	buf.WriteN(p.SrcPort)
	buf.WriteN(p.DstPort)
	buf.WriteN(p.Seq)
	buf.WriteN(p.Ack)

	flags := uint16(p.DataOff) << 12

	if p.Flags&Fin != 0 {
		flags |= 0x0001
	}

	if p.Flags&Syn != 0 {
		flags |= 0x0002
	}

	if p.Flags&Rst != 0 {
		flags |= 0x0004
	}

	if p.Flags&PSH != 0 {
		flags |= 0x0008
	}

	if p.Flags&Ack != 0 {
		flags |= 0x0010
	}

	if p.Flags&Urg != 0 {
		flags |= 0x0020
	}

	if p.Flags&ECE != 0 {
		flags |= 0x0040
	}

	if p.Flags&Cwr != 0 {
		flags |= 0x0080
	}

	if p.Flags&NS != 0 {
		flags |= 0x0100
	}

	buf.WriteN(flags)

	buf.WriteN(p.WindowSize)
	buf.WriteN(uint16(0x0000))
	buf.WriteN(p.Urgent)

	for _, opt := range p.Options {
		buf.WriteN(opt.Type)
		buf.WriteN(opt.Len)
		buf.WriteN(opt.Data)
	}

	if p.csum_seed != 0 {
		p.Checksum =
			ipv4.CalculateChecksum(buf.LayerBytes(), p.csum_seed)
	}

	buf.PutUint16N(16, p.Checksum)

	/* add padding */
	for buf.LayerLen() < int(p.DataOff)*4 {
		buf.WriteN(uint8(0x00))
	}

	return nil
}
예제 #30
0
파일: layers.go 프로젝트: kelixin/go.pkt
// Recursively unpack the given byte slice into a packet. The link_type argument
// must specify the type of the first layer in the input data, successive layers
// will be detected automatically.
//
// Note that unpacking is done without copying the input slice, which means that
// if the slice is modifed, it may affect the packets that where unpacked from
// it. If you can't guarantee that the data slice won't change, you'll need to
// copy it and pass the copy to UnpackAll().
func UnpackAll(buf []byte, link_type packet.Type) (packet.Packet, error) {
	var b packet.Buffer
	b.Init(buf)

	first_pkt := packet.Packet(nil)
	prev_pkt := packet.Packet(nil)

	for link_type != packet.None {
		var p packet.Packet

		if b.Len() <= 0 {
			break
		}

		switch link_type {
		case packet.ARP:
			p = &arp.Packet{}
		case packet.Eth:
			p = &eth.Packet{}
		case packet.ICMPv4:
			p = &icmpv4.Packet{}
		case packet.ICMPv6:
			p = &icmpv6.Packet{}
		case packet.IPv4:
			p = &ipv4.Packet{}
		case packet.IPv6:
			p = &ipv6.Packet{}
		case packet.LLC:
			p = &llc.Packet{}
		case packet.RadioTap:
			p = &radiotap.Packet{}
		case packet.SLL:
			p = &sll.Packet{}
		case packet.SNAP:
			p = &snap.Packet{}
		case packet.TCP:
			p = &tcp.Packet{}
		case packet.UDP:
			p = &udp.Packet{}
		case packet.VLAN:
			p = &vlan.Packet{}
		default:
			p = &raw.Packet{}
		}

		if p == nil {
			break
		}

		b.NewLayer()

		err := p.Unpack(&b)
		if err != nil {
			return nil, err
		}

		if prev_pkt != nil {
			prev_pkt.SetPayload(p)
		} else {
			first_pkt = p
		}

		prev_pkt = p
		link_type = p.GuessPayloadType()
	}

	return first_pkt, nil
}