packet.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package kyoketsu
  2. import (
  3. "fmt"
  4. "net"
  5. "github.com/google/gopacket"
  6. "github.com/google/gopacket/layers"
  7. )
  8. // PacketOption is a function that applies a configuration to a PacketConfig.
  9. type PacketOption func(*PacketConfig) error
  10. // PacketConfig stores configuration for building a packet.
  11. type PacketConfig struct {
  12. SrcIP, DstIP net.IP
  13. SrcPort, DstPort layers.TCPPort
  14. SrcMAC, DstMAC net.HardwareAddr
  15. PayloadSize int
  16. }
  17. func buildPayload(payloadSize int) []byte {
  18. payload := make([]byte, payloadSize)
  19. for i := range payload {
  20. payload[i] = byte(i % 256) // Example payload; adjust as needed
  21. }
  22. return payload
  23. }
  24. // WithEthernetLayer enables the Ethernet layer in the packet.
  25. func WithEthernetLayer(srcMAC, dstMAC net.HardwareAddr) PacketOption {
  26. return func(c *PacketConfig) error {
  27. c.SrcMAC = srcMAC
  28. c.DstMAC = dstMAC
  29. return nil
  30. }
  31. }
  32. // WithIpLayer enables the IP layer in the packet.
  33. func WithIpLayer(srcIp, dstIp net.IP) PacketOption {
  34. return func(c *PacketConfig) error {
  35. c.SrcIP = srcIp
  36. c.DstIP = dstIp
  37. return nil
  38. }
  39. }
  40. // WithPayloadSize sets the payload size for the packet.
  41. func WithPayloadSize(size int) PacketOption {
  42. return func(c *PacketConfig) error {
  43. c.PayloadSize = size
  44. return nil
  45. }
  46. }
  47. // NewPacketConfig creates a new PacketConfig with specified options.
  48. func NewPacketConfig(opts ...PacketOption) (*PacketConfig, error) {
  49. config := &PacketConfig{}
  50. for _, opt := range opts {
  51. if err := opt(config); err != nil {
  52. return nil, err
  53. }
  54. }
  55. return config, nil
  56. }
  57. // BuildPacket constructs the packet based on the PacketConfig.
  58. // It automatically includes the Ethernet layer if both SrcMAC and DstMAC are provided.
  59. func BuildPacket(c *PacketConfig) ([]byte, error) {
  60. buf := gopacket.NewSerializeBuffer()
  61. var layersToSerialize []gopacket.SerializableLayer
  62. // Automatically include the Ethernet layer if MAC addresses are provided
  63. if c.SrcMAC != nil && c.DstMAC != nil {
  64. ethLayer := &layers.Ethernet{
  65. SrcMAC: c.SrcMAC,
  66. DstMAC: c.DstMAC,
  67. EthernetType: layers.EthernetTypeIPv4,
  68. }
  69. layersToSerialize = append(layersToSerialize, ethLayer)
  70. }
  71. // Set IP layer
  72. ipLayer := &layers.IPv4{
  73. Version: 4,
  74. TTL: 64,
  75. SrcIP: c.SrcIP,
  76. DstIP: c.DstIP,
  77. Protocol: layers.IPProtocolTCP,
  78. }
  79. layersToSerialize = append(layersToSerialize, ipLayer)
  80. payload := make([]byte, c.PayloadSize)
  81. // Optionally, fill the payload with data
  82. layersToSerialize = append(layersToSerialize, gopacket.Payload(payload))
  83. // Serialize the packet layers into the buffer
  84. if err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{ComputeChecksums: true, FixLengths: true}, layersToSerialize...); err != nil {
  85. return nil, fmt.Errorf("error serializing packet: %w", err)
  86. }
  87. return buf.Bytes(), nil
  88. }