Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #17 from gconnell/master

VLAN tagging (802.1Q) support
  • Loading branch information...
commit 15f4207d6b51cdfb272f4dd608271262f01856b4 2 parents 066cff1 + 8b55de9
@akrennmair authored
Showing with 69 additions and 6 deletions.
  1. +36 −3 decode.go
  2. +30 −0 decode_test.go
  3. +1 −1  io.go
  4. +2 −2 pcap.go
View
39 decode.go
@@ -9,9 +9,10 @@ import (
)
const (
- TYPE_IP = 0x0800
- TYPE_ARP = 0x0806
- TYPE_IP6 = 0x86DD
+ TYPE_IP = 0x0800
+ TYPE_ARP = 0x0806
+ TYPE_IP6 = 0x86DD
+ TYPE_VLAN = 0x8100
IP_ICMP = 1
IP_INIP = 4
@@ -82,6 +83,8 @@ func (p *Packet) Decode() {
p.decodeIp6()
case TYPE_ARP:
p.decodeArp()
+ case TYPE_VLAN:
+ p.decodeVlan()
}
}
@@ -233,6 +236,36 @@ func (ip *Iphdr) SrcAddr() string { return net.IP(ip.SrcIp).String() }
func (ip *Iphdr) DestAddr() string { return net.IP(ip.DestIp).String() }
func (ip *Iphdr) Len() int { return int(ip.Length) }
+type Vlanhdr struct {
+ Priority byte
+ DropEligible bool
+ VlanIdentifier int
+ Type int // Not actually part of the vlan header, but the type of the actual packet
+}
+
+func (v *Vlanhdr) String() {
+ fmt.Sprintf("VLAN Prioity:%d Drop:%v Tag:%d", v.Prioity, v.DropEligible, v.VlanIdentifier)
+}
+
+func (p *Packet) decodeVlan() {
+ pkt := p.Payload
+ vlan := new(Vlanhdr)
+ vlan.Priority = (pkt[2] & 0xE0) >> 13
+ vlan.DropEligible = pkt[2]&0x10 != 0
+ vlan.VlanIdentifier = int(binary.BigEndian.Uint16(pkt[:2])) & 0x0FFF
+ vlan.Type = int(binary.BigEndian.Uint16(p.Payload[2:4]))
+ p.Headers = append(p.Headers, vlan)
+ p.Payload = p.Payload[4:]
+ switch vlan.Type {
+ case TYPE_IP:
+ p.decodeIp()
+ case TYPE_IP6:
+ p.decodeIp6()
+ case TYPE_ARP:
+ p.decodeArp()
+ }
+}
+
type Tcphdr struct {
SrcPort uint16
DestPort uint16
View
30 decode_test.go
@@ -162,3 +162,33 @@ func TestDecodeSmallTcpPacketHasEmptyPayload(t *testing.T) {
t.Error("Non-empty payload:", p.Payload)
}
}
+
+func TestDecodeVlanPacket(t *testing.T) {
+ p := &Packet{
+ Data: []byte{
+ 0x00, 0x10, 0xdb, 0xff, 0x10, 0x00, 0x00, 0x15, 0x2c, 0x9d, 0xcc, 0x00, 0x81, 0x00, 0x01, 0xf7,
+ 0x08, 0x00, 0x45, 0x00, 0x00, 0x28, 0x29, 0x8d, 0x40, 0x00, 0x7d, 0x06, 0x83, 0xa0, 0xac, 0x1b,
+ 0xca, 0x8e, 0x45, 0x16, 0x94, 0xe2, 0xd4, 0x0a, 0x00, 0x50, 0xdf, 0xab, 0x9c, 0xc6, 0xcd, 0x1e,
+ 0xe5, 0xd1, 0x50, 0x10, 0x01, 0x00, 0x5a, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ }}
+ p.Decode()
+ if p.Type != TYPE_VLAN {
+ t.Error("Didn't detect vlan")
+ }
+ if len(p.Headers) != 3 {
+ t.Error("Incorrect number of headers:", len(p.Headers))
+ for i, h := range p.Headers {
+ t.Errorf("Header %d: %#v", i, h)
+ }
+ t.FailNow()
+ }
+ if _, ok := p.Headers[0].(*Vlanhdr); !ok {
+ t.Errorf("First header isn't vlan: %q", p.Headers[0])
+ }
+ if _, ok := p.Headers[1].(*Iphdr); !ok {
+ t.Errorf("Second header isn't IP: %q", p.Headers[1])
+ }
+ if _, ok := p.Headers[2].(*Tcphdr); !ok {
+ t.Errorf("Third header isn't TCP: %q", p.Headers[2])
+ }
+}
View
2  io.go
@@ -107,7 +107,7 @@ func (r *Reader) Next() *Packet {
return nil
}
return &Packet{
- Time: time.Unix(int64(timeSec), int64(timeUsec)),
+ Time: time.Unix(int64(timeSec), int64(timeUsec)),
Caplen: capLen,
Len: origLen,
Data: data,
View
4 pcap.go
@@ -17,8 +17,8 @@ import (
"errors"
"net"
"syscall"
- "unsafe"
"time"
+ "unsafe"
)
type Pcap struct {
@@ -44,7 +44,7 @@ type IFAddress struct {
// TODO: add broadcast + PtP dst ?
}
-func (p *Pcap) Next() (pkt *Packet) {
+func (p *Pcap) Next() (pkt *Packet) {
rv, _ := p.NextEx()
return rv
}
Please sign in to comment.
Something went wrong with that request. Please try again.