github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/utils/packetgen/packet_gen.go (about)

     1  //Package packetgen "PacketGen" is a Packet Generator library
     2  //Current version: V1.0, Updates are coming soon
     3  package packetgen
     4  
     5  //Go libraries
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"net"
    10  
    11  	"github.com/google/gopacket"
    12  	"github.com/google/gopacket/layers"
    13  )
    14  
    15  //NewPacket returns a packet strut which implements PacketManipulator
    16  func NewPacket() PacketManipulator {
    17  
    18  	return &Packet{}
    19  }
    20  
    21  //AddEthernetLayer creates an Ethernet layer
    22  func (p *Packet) AddEthernetLayer(srcMACstr string, dstMACstr string) error {
    23  
    24  	if p.ethernetLayer != nil {
    25  		return errors.New("ethernet layer already exists")
    26  	}
    27  
    28  	var srcMAC, dstMAC net.HardwareAddr
    29  
    30  	//MAC address of the source
    31  	srcMAC, _ = net.ParseMAC(srcMACstr)
    32  
    33  	if srcMAC == nil {
    34  		return errors.New("no source mac given")
    35  	}
    36  
    37  	//MAC address of the destination
    38  	dstMAC, _ = net.ParseMAC(dstMACstr)
    39  
    40  	if dstMAC == nil {
    41  		return errors.New("no destination mac given")
    42  	}
    43  
    44  	//Ethernet packet header
    45  	p.ethernetLayer = &layers.Ethernet{
    46  		SrcMAC:       srcMAC,
    47  		DstMAC:       dstMAC,
    48  		EthernetType: layers.EthernetTypeIPv4,
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  //GetEthernetPacket returns the ethernet layer created
    55  func (p *Packet) GetEthernetPacket() layers.Ethernet {
    56  
    57  	return *p.ethernetLayer
    58  }
    59  
    60  //AddIPLayer creates an IP layer
    61  func (p *Packet) AddIPLayer(srcIPstr string, dstIPstr string) error {
    62  
    63  	if p.ipLayer != nil {
    64  		return errors.New("ip layer already exists")
    65  	}
    66  
    67  	var srcIP, dstIP net.IP
    68  
    69  	//IP address of the source
    70  	srcIP = net.ParseIP(srcIPstr)
    71  
    72  	if srcIP == nil {
    73  		return errors.New("no source ip given")
    74  	}
    75  
    76  	//IP address of the destination
    77  	dstIP = net.ParseIP(dstIPstr)
    78  
    79  	if dstIP == nil {
    80  		return errors.New("no destination ip given")
    81  	}
    82  
    83  	//IP packet header
    84  	p.ipLayer = &layers.IPv4{
    85  		SrcIP:    srcIP,
    86  		DstIP:    dstIP,
    87  		Version:  4,
    88  		TTL:      64,
    89  		Protocol: layers.IPProtocolTCP,
    90  	}
    91  
    92  	return nil
    93  }
    94  
    95  //GetIPChecksum returns IP cheksum
    96  func (p *Packet) GetIPChecksum() uint16 {
    97  
    98  	return p.ipLayer.Checksum
    99  }
   100  
   101  //GetIPPacket returns IP checksum
   102  func (p *Packet) GetIPPacket() layers.IPv4 {
   103  
   104  	return *p.ipLayer
   105  }
   106  
   107  //AddTCPLayer creates a TCP layer
   108  func (p *Packet) AddTCPLayer(srcPort layers.TCPPort, dstPort layers.TCPPort) error {
   109  
   110  	if p.tcpLayer != nil {
   111  		return errors.New("tcp layer already exists")
   112  	}
   113  
   114  	if srcPort == 0 {
   115  		return errors.New("no source tcp port given")
   116  	}
   117  
   118  	if dstPort == 0 {
   119  		return errors.New("no destination tcp port given")
   120  	}
   121  
   122  	//TCP packet header
   123  	p.tcpLayer = &layers.TCP{
   124  		SrcPort: srcPort,
   125  		DstPort: dstPort,
   126  		Window:  0,
   127  		Urgent:  0,
   128  		Seq:     0,
   129  		Ack:     0,
   130  		ACK:     false,
   131  		SYN:     false,
   132  		FIN:     false,
   133  		RST:     false,
   134  		URG:     false,
   135  		ECE:     false,
   136  		CWR:     false,
   137  		NS:      false,
   138  		PSH:     false,
   139  	}
   140  
   141  	return p.tcpLayer.SetNetworkLayerForChecksum(p.ipLayer)
   142  }
   143  
   144  //GetTCPPacket returns created TCP packet
   145  func (p *Packet) GetTCPPacket() layers.TCP {
   146  
   147  	return *p.tcpLayer
   148  }
   149  
   150  //GetTCPSequenceNumber returns TCP Sequence number
   151  func (p *Packet) GetTCPSequenceNumber() uint32 {
   152  
   153  	return p.tcpLayer.Seq
   154  }
   155  
   156  //GetTCPAcknowledgementNumber returns TCP Acknowledgement number
   157  func (p *Packet) GetTCPAcknowledgementNumber() uint32 {
   158  
   159  	return p.tcpLayer.Ack
   160  }
   161  
   162  //GetTCPWindow returns TCP Window
   163  func (p *Packet) GetTCPWindow() uint16 {
   164  
   165  	return p.tcpLayer.Window
   166  }
   167  
   168  //GetTCPSyn returns TCP SYN flag
   169  func (p *Packet) GetTCPSyn() bool {
   170  
   171  	return p.tcpLayer.SYN
   172  }
   173  
   174  //GetTCPAck returns TCP ACK flag
   175  func (p *Packet) GetTCPAck() bool {
   176  
   177  	return p.tcpLayer.ACK
   178  }
   179  
   180  //GetTCPFin returns TCP FIN flag
   181  func (p *Packet) GetTCPFin() bool {
   182  
   183  	return p.tcpLayer.FIN
   184  }
   185  
   186  //GetTCPChecksum returns TCP checksum
   187  func (p *Packet) GetTCPChecksum() uint16 {
   188  
   189  	return p.tcpLayer.Checksum
   190  }
   191  
   192  //SetTCPSequenceNumber changes TCP sequence number
   193  func (p *Packet) SetTCPSequenceNumber(seqNum uint32) {
   194  
   195  	p.tcpLayer.Seq = seqNum
   196  
   197  }
   198  
   199  //SetTCPAcknowledgementNumber changes TCP Acknowledgement number
   200  func (p *Packet) SetTCPAcknowledgementNumber(ackNum uint32) {
   201  
   202  	p.tcpLayer.Ack = ackNum
   203  
   204  }
   205  
   206  //SetTCPWindow changes the TCP window
   207  func (p *Packet) SetTCPWindow(window uint16) {
   208  
   209  	p.tcpLayer.Window = window
   210  
   211  }
   212  
   213  //SetTCPSyn changes the TCP SYN flag to true
   214  func (p *Packet) SetTCPSyn() {
   215  
   216  	p.tcpLayer.SYN = true
   217  	p.tcpLayer.ACK = false
   218  	p.tcpLayer.FIN = false
   219  }
   220  
   221  //SetTCPSynAck changes the TCP SYN and ACK flag to true
   222  func (p *Packet) SetTCPSynAck() {
   223  
   224  	p.tcpLayer.SYN = true
   225  	p.tcpLayer.ACK = true
   226  	p.tcpLayer.FIN = false
   227  }
   228  
   229  //SetTCPAck changes the TCP ACK flag to true
   230  func (p *Packet) SetTCPAck() {
   231  
   232  	p.tcpLayer.SYN = false
   233  	p.tcpLayer.ACK = true
   234  	p.tcpLayer.FIN = false
   235  }
   236  
   237  //SetTCPCwr changes the TCP CWR flag to true
   238  func (p *Packet) SetTCPCwr() {
   239  	p.tcpLayer.CWR = true
   240  }
   241  
   242  //SetTCPEce changes the TCP ECE flag to true
   243  func (p *Packet) SetTCPEce() {
   244  	p.tcpLayer.ECE = true
   245  }
   246  
   247  //SetTCPUrg changes the TCP URG flag to true
   248  func (p *Packet) SetTCPUrg() {
   249  	p.tcpLayer.URG = true
   250  }
   251  
   252  //SetTCPPsh changes the TCP PSH flag to true
   253  func (p *Packet) SetTCPPsh() {
   254  	p.tcpLayer.PSH = true
   255  }
   256  
   257  //SetTCPRst changes the TCP RST flag to true
   258  func (p *Packet) SetTCPRst() {
   259  	p.tcpLayer.RST = true
   260  }
   261  
   262  //SetTCPFin changes the TCP FIN flag to true
   263  func (p *Packet) SetTCPFin() {
   264  	p.tcpLayer.FIN = true
   265  }
   266  
   267  //NewTCPPayload adds new payload to TCP layer
   268  func (p *Packet) NewTCPPayload(newPayload string) error {
   269  
   270  	if p.tcpLayer.Payload != nil {
   271  		return errors.New("payload already exists")
   272  	}
   273  
   274  	p.tcpLayer.Payload = []byte(newPayload)
   275  
   276  	return nil
   277  }
   278  
   279  //ToBytes creates a packet buffer and converts it into a complete packet with ethernet, IP and TCP (with options)
   280  func (p *Packet) ToBytes() ([]byte, error) {
   281  
   282  	opts := gopacket.SerializeOptions{
   283  		FixLengths:       true, //fix lengths based on the payload (data)
   284  		ComputeChecksums: true, //compute checksum based on the payload during serialization
   285  	}
   286  
   287  	if err := p.tcpLayer.SetNetworkLayerForChecksum(p.ipLayer); err != nil {
   288  		return nil, fmt.Errorf("unable to compute checksum: %s", err)
   289  	}
   290  
   291  	//Creating a packet buffer by serializing the ethernet, IP and TCP layers/packets
   292  	packetBuf := gopacket.NewSerializeBuffer()
   293  	tcpPayload := gopacket.Payload(p.tcpLayer.Payload)
   294  	if err := gopacket.SerializeLayers(packetBuf, opts, p.ethernetLayer, p.ipLayer, p.tcpLayer, tcpPayload); err != nil {
   295  		return nil, fmt.Errorf("unable to serialize layers: %s", err)
   296  	}
   297  	//Converting into bytes and removing the ethernet from the layers
   298  	bytes := packetBuf.Bytes()
   299  	bytesWithoutEthernet := bytes[14:]
   300  
   301  	var finalBytes []byte
   302  	finalBytes = append(finalBytes, bytesWithoutEthernet...)
   303  
   304  	return finalBytes, nil
   305  }
   306  
   307  //NewTemplateFlow will return flow of packets which implements PacketManipulator
   308  func NewTemplateFlow() PacketFlowManipulator {
   309  
   310  	return &PacketFlow{}
   311  }
   312  
   313  //AddPacket is a helper method to add the packet from the template to the struct internal struct field
   314  func (p *Packet) AddPacket(packet gopacket.Packet) {
   315  
   316  	p.packet = packet
   317  
   318  }
   319  
   320  //DecodePacket returns decoded packet which implements PacketManipulator
   321  func (p *Packet) DecodePacket() PacketManipulator {
   322  
   323  	packetData := &Packet{
   324  		ethernetLayer: &layers.Ethernet{},
   325  		ipLayer:       &layers.IPv4{},
   326  		tcpLayer:      &layers.TCP{},
   327  	}
   328  
   329  	newEthernetPacket := packetData.GetEthernetPacket()
   330  	newIPPacket := packetData.GetIPPacket()
   331  	newTCPPacket := packetData.GetTCPPacket()
   332  
   333  	if ethernetLayer := p.packet.Layer(layers.LayerTypeEthernet); ethernetLayer != nil {
   334  		ethernet, _ := ethernetLayer.(*layers.Ethernet)
   335  		newEthernetPacket.SrcMAC = ethernet.SrcMAC
   336  		newEthernetPacket.DstMAC = ethernet.DstMAC
   337  		newEthernetPacket.EthernetType = ethernet.EthernetType
   338  	}
   339  
   340  	if ipLayer := p.packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
   341  		ip, _ := ipLayer.(*layers.IPv4)
   342  
   343  		newIPPacket.SrcIP = ip.SrcIP
   344  		newIPPacket.DstIP = ip.DstIP
   345  		newIPPacket.Version = ip.Version
   346  		newIPPacket.Length = ip.Length
   347  		newIPPacket.Protocol = ip.Protocol
   348  		newIPPacket.TTL = ip.TTL
   349  	}
   350  
   351  	if tcpLayer := p.packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
   352  		tcp, _ := tcpLayer.(*layers.TCP)
   353  
   354  		newTCPPacket.SrcPort = tcp.SrcPort
   355  		newTCPPacket.DstPort = tcp.DstPort
   356  		newTCPPacket.Seq = tcp.Seq
   357  		newTCPPacket.Ack = tcp.Ack
   358  		newTCPPacket.SYN = tcp.SYN
   359  		newTCPPacket.FIN = tcp.FIN
   360  		newTCPPacket.RST = tcp.RST
   361  		newTCPPacket.PSH = tcp.PSH
   362  		newTCPPacket.ACK = tcp.ACK
   363  		newTCPPacket.URG = tcp.URG
   364  		newTCPPacket.ECE = tcp.ECE
   365  		newTCPPacket.CWR = tcp.CWR
   366  		newTCPPacket.NS = tcp.NS
   367  		newTCPPacket.Checksum = tcp.Checksum
   368  		newTCPPacket.Window = tcp.Window
   369  	}
   370  
   371  	packetData = &Packet{
   372  		ethernetLayer: &newEthernetPacket,
   373  		ipLayer:       &newIPPacket,
   374  		tcpLayer:      &newTCPPacket,
   375  	}
   376  
   377  	return packetData
   378  }
   379  
   380  //NewPacketFlow returns PacketFlow struct which implements PacketFlowManipulator
   381  func NewPacketFlow(smac string, dmac string, sip string, dip string, sport layers.TCPPort, dport layers.TCPPort) PacketFlowManipulator {
   382  
   383  	initialTupules := &PacketFlow{
   384  		sMAC:  smac,
   385  		dMAC:  dmac,
   386  		sIP:   sip,
   387  		dIP:   dip,
   388  		sPort: sport,
   389  		dPort: dport,
   390  		flow:  make([]PacketManipulator, 0),
   391  	}
   392  
   393  	return initialTupules
   394  }
   395  
   396  //GenerateTCPFlow returns an array of PacketFlowManipulator interface
   397  func (p *PacketFlow) GenerateTCPFlow(pt PacketFlowType) (PacketFlowManipulator, error) {
   398  
   399  	if pt == 0 {
   400  		//Create a SYN packet to initialize the flow
   401  		firstPacket := NewPacket()
   402  		if err := firstPacket.AddEthernetLayer(p.sMAC, p.dMAC); err != nil {
   403  			return nil, fmt.Errorf("unable tp add ethernet layer: %s", err)
   404  		}
   405  		if err := firstPacket.AddIPLayer(p.sIP, p.dIP); err != nil {
   406  			return nil, fmt.Errorf("unable to add ip layer: %s", err)
   407  		}
   408  		if err := firstPacket.AddTCPLayer(p.sPort, p.dPort); err != nil {
   409  			return nil, fmt.Errorf("unable to add tcp layer: %s", err)
   410  		}
   411  		firstPacket.SetTCPSyn()
   412  		firstPacket.SetTCPSequenceNumber(firstPacket.GetTCPSequenceNumber())
   413  		firstPacket.SetTCPAcknowledgementNumber(firstPacket.GetTCPAcknowledgementNumber())
   414  		synPacket, _ := firstPacket.(*Packet)
   415  
   416  		p.flow = append(p.flow, synPacket)
   417  
   418  		//Create a SynAck packet
   419  		secondPacket := NewPacket()
   420  		if err := secondPacket.AddEthernetLayer(p.sMAC, p.dMAC); err != nil {
   421  			return nil, fmt.Errorf("unable to add ethernet layer: %s", err)
   422  		}
   423  		if err := secondPacket.AddIPLayer(p.dIP, p.sIP); err != nil {
   424  			return nil, fmt.Errorf("unable to add ip layer: %s", err)
   425  		}
   426  		if err := secondPacket.AddTCPLayer(p.dPort, p.sPort); err != nil {
   427  			return nil, fmt.Errorf("unable to add tcp layer: %s", err)
   428  		}
   429  		secondPacket.SetTCPSynAck()
   430  		secondPacket.SetTCPSequenceNumber(0)
   431  		secondPacket.SetTCPAcknowledgementNumber(firstPacket.GetTCPSequenceNumber() + 1)
   432  		synackPacket, _ := secondPacket.(*Packet)
   433  
   434  		p.flow = append(p.flow, synackPacket)
   435  
   436  		//Create an Ack Packet
   437  		thirdPacket := NewPacket()
   438  		if err := thirdPacket.AddEthernetLayer(p.sMAC, p.dMAC); err != nil {
   439  			return nil, fmt.Errorf("unable tp add ethernet layer: %s", err)
   440  		}
   441  		if err := thirdPacket.AddIPLayer(p.sIP, p.dIP); err != nil {
   442  			return nil, fmt.Errorf("unable to add ip layer: %s", err)
   443  		}
   444  		if err := thirdPacket.AddTCPLayer(p.sPort, p.dPort); err != nil {
   445  			return nil, fmt.Errorf("unable to add tcp layer: %s", err)
   446  		}
   447  		thirdPacket.SetTCPAck()
   448  		thirdPacket.SetTCPSequenceNumber(secondPacket.GetTCPAcknowledgementNumber())
   449  		thirdPacket.SetTCPAcknowledgementNumber(secondPacket.GetTCPSequenceNumber() + 1)
   450  		ackPacket, _ := thirdPacket.(*Packet)
   451  
   452  		p.flow = append(p.flow, ackPacket)
   453  
   454  		return p, nil
   455  
   456  	} else if pt == 1 {
   457  
   458  		for i := 0; i < len(PacketFlowTemplate1); i++ {
   459  			//Create a Packet type variable to store decoded packet
   460  			newPacket := NewPacket()
   461  			packet := gopacket.NewPacket(PacketFlowTemplate1[i], layers.LayerTypeEthernet, gopacket.Default)
   462  			newPacket.AddPacket(packet)
   463  
   464  			p.flow = append(p.flow, newPacket.DecodePacket())
   465  
   466  		}
   467  
   468  		return p, nil
   469  	} else if pt == 2 {
   470  
   471  		for i := 0; i < len(PacketFlowTemplate2); i++ {
   472  
   473  			//Create a Packet type variable to store decoded packet
   474  			newPacket := NewPacket()
   475  			packet := gopacket.NewPacket(PacketFlowTemplate2[i], layers.LayerTypeEthernet, gopacket.Default)
   476  			newPacket.AddPacket(packet)
   477  
   478  			p.flow = append(p.flow, newPacket.DecodePacket())
   479  
   480  		}
   481  
   482  		return p, nil
   483  	} else if pt == 3 {
   484  
   485  		for i := 0; i < len(PacketFlowTemplate3); i++ {
   486  
   487  			//Create a Packet type variable to store decoded packet
   488  			newPacket := NewPacket()
   489  			packet := gopacket.NewPacket(PacketFlowTemplate3[i], layers.LayerTypeEthernet, gopacket.Default)
   490  			newPacket.AddPacket(packet)
   491  
   492  			p.flow = append(p.flow, newPacket.DecodePacket())
   493  
   494  		}
   495  
   496  		return p, nil
   497  	}
   498  
   499  	return nil, nil
   500  }
   501  
   502  //GenerateTCPFlowPayload Coming soon...
   503  func (p *PacketFlow) GenerateTCPFlowPayload(newPayload string) PacketFlowManipulator {
   504  
   505  	return nil
   506  }
   507  
   508  //AppendPacket adds the packet to Flow field of PacketFlowManipulator interface
   509  func (p *PacketFlow) AppendPacket(pm PacketManipulator) int {
   510  
   511  	p.flow = append(p.flow, pm)
   512  
   513  	return p.GetNumPackets()
   514  }
   515  
   516  //GetMatchPackets implicitly returns the matching packets requested by the user
   517  func (p *PacketFlow) getMatchPackets(syn, ack, fin bool) PacketFlowManipulator {
   518  
   519  	packetsInFlow := NewPacketFlow(p.sMAC, p.dMAC, p.sIP, p.dIP, p.sPort, p.dPort)
   520  
   521  	for j := 0; j < len(p.flow); j++ {
   522  		if p.flow[j].GetTCPSyn() == syn && p.flow[j].GetTCPAck() == ack && p.flow[j].GetTCPFin() == fin {
   523  			packetsInFlow.AppendPacket(p.flow[j])
   524  		}
   525  	}
   526  
   527  	return packetsInFlow
   528  }
   529  
   530  //GetFirstSynPacket return first Syn packet from the flow
   531  func (p *PacketFlow) GetFirstSynPacket() PacketManipulator {
   532  
   533  	return p.GetSynPackets().GetNthPacket(0)
   534  }
   535  
   536  //GetFirstSynAckPacket return first SynAck packet from the flow
   537  func (p *PacketFlow) GetFirstSynAckPacket() PacketManipulator {
   538  
   539  	return p.GetSynAckPackets().GetNthPacket(0)
   540  }
   541  
   542  //GetFirstAckPacket return first Ack packet from the flow
   543  func (p *PacketFlow) GetFirstAckPacket() PacketManipulator {
   544  
   545  	return p.GetAckPackets().GetNthPacket(0)
   546  }
   547  
   548  //GetSynPackets returns the SYN packets
   549  func (p *PacketFlow) GetSynPackets() PacketFlowManipulator {
   550  
   551  	return p.getMatchPackets(true, false, false)
   552  }
   553  
   554  //GetSynAckPackets returns the SynAck packets
   555  func (p *PacketFlow) GetSynAckPackets() PacketFlowManipulator {
   556  
   557  	return p.getMatchPackets(true, true, false)
   558  }
   559  
   560  //GetAckPackets returns the Ack Packets
   561  func (p *PacketFlow) GetAckPackets() PacketFlowManipulator {
   562  
   563  	return p.getMatchPackets(false, true, false)
   564  }
   565  
   566  //GetUptoFirstSynAckPacket will return packets upto first SynAck packet
   567  func (p *PacketFlow) GetUptoFirstSynAckPacket() PacketFlowManipulator {
   568  
   569  	packetsInFlow := NewPacketFlow(p.sMAC, p.dMAC, p.sIP, p.dIP, p.sPort, p.dPort)
   570  	flag := false
   571  
   572  	for j := 0; j < len(p.flow); j++ {
   573  		if !flag {
   574  			packetsInFlow.AppendPacket(p.flow[j])
   575  			if p.flow[j].GetTCPSyn() && p.flow[j].GetTCPAck() && !p.flow[j].GetTCPFin() {
   576  				flag = true
   577  			}
   578  		}
   579  	}
   580  
   581  	return packetsInFlow
   582  }
   583  
   584  //GetUptoFirstAckPacket will return packets upto first Ack packet
   585  func (p *PacketFlow) GetUptoFirstAckPacket() PacketFlowManipulator {
   586  
   587  	packetsInFlow := NewPacketFlow(p.sMAC, p.dMAC, p.sIP, p.dIP, p.sPort, p.dPort)
   588  	flag := false
   589  
   590  	for j := 0; j < len(p.flow); j++ {
   591  		if !flag {
   592  			packetsInFlow.AppendPacket(p.flow[j])
   593  			if !p.flow[j].GetTCPSyn() && p.flow[j].GetTCPAck() && !p.flow[j].GetTCPFin() {
   594  				flag = true
   595  			}
   596  		}
   597  	}
   598  
   599  	return packetsInFlow
   600  }
   601  
   602  //GetNthPacket returns the packet requested by the user from the array
   603  func (p *PacketFlow) GetNthPacket(index int) PacketManipulator {
   604  
   605  	for i := 0; i < len(p.flow); i++ {
   606  		if index == i {
   607  			return p.flow[i]
   608  		}
   609  	}
   610  
   611  	panic("Index out of range")
   612  }
   613  
   614  //GetNumPackets returns an array of packets
   615  func (p *PacketFlow) GetNumPackets() int {
   616  
   617  	return len(p.flow)
   618  }