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 }
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 }