123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package kyoketsu
- import (
- "fmt"
- "net"
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- )
- type PacketOption func(*PacketConfig) error
- type PacketConfig struct {
- SrcIP, DstIP net.IP
- SrcPort, DstPort layers.TCPPort
- SrcMAC, DstMAC net.HardwareAddr
- PayloadSize int
- }
- func buildPayload(payloadSize int) []byte {
- payload := make([]byte, payloadSize)
- for i := range payload {
- payload[i] = byte(i % 256)
- }
- return payload
- }
- func WithEthernetLayer(srcMAC, dstMAC net.HardwareAddr) PacketOption {
- return func(c *PacketConfig) error {
- c.SrcMAC = srcMAC
- c.DstMAC = dstMAC
- return nil
- }
- }
- func WithIpLayer(srcIp, dstIp net.IP) PacketOption {
- return func(c *PacketConfig) error {
- c.SrcIP = srcIp
- c.DstIP = dstIp
- return nil
- }
- }
- func WithPayloadSize(size int) PacketOption {
- return func(c *PacketConfig) error {
- c.PayloadSize = size
- return nil
- }
- }
- func NewPacketConfig(opts ...PacketOption) (*PacketConfig, error) {
- config := &PacketConfig{}
- for _, opt := range opts {
- if err := opt(config); err != nil {
- return nil, err
- }
- }
- return config, nil
- }
- func BuildPacket(c *PacketConfig) ([]byte, error) {
- buf := gopacket.NewSerializeBuffer()
- var layersToSerialize []gopacket.SerializableLayer
-
- if c.SrcMAC != nil && c.DstMAC != nil {
- ethLayer := &layers.Ethernet{
- SrcMAC: c.SrcMAC,
- DstMAC: c.DstMAC,
- EthernetType: layers.EthernetTypeIPv4,
- }
- layersToSerialize = append(layersToSerialize, ethLayer)
- }
-
- ipLayer := &layers.IPv4{
- Version: 4,
- TTL: 64,
- SrcIP: c.SrcIP,
- DstIP: c.DstIP,
- Protocol: layers.IPProtocolTCP,
- }
- layersToSerialize = append(layersToSerialize, ipLayer)
- payload := make([]byte, c.PayloadSize)
-
- layersToSerialize = append(layersToSerialize, gopacket.Payload(payload))
-
- if err := gopacket.SerializeLayers(buf, gopacket.SerializeOptions{ComputeChecksums: true, FixLengths: true}, layersToSerialize...); err != nil {
- return nil, fmt.Errorf("error serializing packet: %w", err)
- }
- return buf.Bytes(), nil
- }
|