1
0
Protocol/packets/packet.go

90 lines
1.9 KiB
Go

package packets
import (
"fmt"
"io"
"time"
)
// Packet is the base struct for all EverQuest packet types
type Packet struct {
Buffer []byte
Opcode uint16
SrcIP uint32
DstIP uint32
SrcPort uint16
DstPort uint16
Priority uint32
Timestamp time.Time
Version int16
}
// NewPacket creates a new packet with the given opcode and data
func NewPacket(opcode uint16, data []byte) *Packet {
p := &Packet{
Opcode: opcode,
Timestamp: time.Now(),
}
if len(data) > 0 {
p.Buffer = make([]byte, len(data))
copy(p.Buffer, data)
}
return p
}
// Size returns the total packet size including opcode
func (p *Packet) Size() uint32 {
return uint32(len(p.Buffer)) + 2
}
// RawOpcode returns the raw opcode value
func (p *Packet) RawOpcode() uint16 {
return p.Opcode
}
// SetSrcInfo sets source IP and port
func (p *Packet) SetSrcInfo(ip uint32, port uint16) {
p.SrcIP = ip
p.SrcPort = port
}
// SetDstInfo sets destination IP and port
func (p *Packet) SetDstInfo(ip uint32, port uint16) {
p.DstIP = ip
p.DstPort = port
}
// CopyInfo copies network and timing info from another packet
func (p *Packet) CopyInfo(other *Packet) {
p.SrcIP = other.SrcIP
p.SrcPort = other.SrcPort
p.DstIP = other.DstIP
p.DstPort = other.DstPort
p.Timestamp = other.Timestamp
p.Version = other.Version
}
// DumpRaw writes packet contents to writer for debugging
func (p *Packet) DumpRaw(w io.Writer) {
p.DumpRawHeader(0xffff, w)
if len(p.Buffer) > 0 {
// TODO: Implement dump_message_column equivalent
fmt.Fprintf(w, "[Data: %d bytes]\n", len(p.Buffer))
}
}
// DumpRawHeader writes packet header info to writer
func (p *Packet) DumpRawHeader(seq uint16, w io.Writer) {
if p.SrcIP != 0 {
fmt.Fprintf(w, "[%s:%d->%s:%d] ",
longToIP(p.SrcIP), p.SrcPort,
longToIP(p.DstIP), p.DstPort)
}
if seq != 0xffff {
fmt.Fprintf(w, "[Seq=%d] ", seq)
}
fmt.Fprintf(w, "[OpCode 0x%04x Size=%d]\n", p.Opcode, len(p.Buffer))
}