Skip to content

Commit

Permalink
change function and param name
Browse files Browse the repository at this point in the history
Signed-off-by: Aryan Bakliwal <aryanbakliwal12345@gmail.com>
  • Loading branch information
AryanBakliwal committed Feb 7, 2025
1 parent 077484e commit d990beb
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
44 changes: 25 additions & 19 deletions pkg/agent/packetcapture/capture/bpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,18 @@ func calculateSkipFalse(srcPort, dstPort uint16) uint8 {
return count
}

func compareIPPort(srcAddrVal, dstAddrVal uint32, size, curLen uint8, srcPort, dstPort uint16, useSkipFalse bool) []bpf.Instruction {
// Generates IP address and port matching instructions
func compileIPPortFilter(srcAddrVal, dstAddrVal uint32, size, curLen uint8, srcPort, dstPort uint16, skipRequestCheck bool) []bpf.Instruction {
inst := []bpf.Instruction{}

// from here we need to check the inst length to calculate skipFalse. If no protocol is set, there will be no related bpf instructions.
if useSkipFalse {

// In the previous instruction, we load the packet's source IP. We then compare it with the source IP from the packet spec to determine if
// the packet is a request (from source to destination). When capturing packets in Both directions, if the source IPs do not match,
// we need to check if the packet is a response (from destination to source). In this case, we skip to the instruction where we compare the
// loaded source IP with the destination IP from the packet spec. The skipRequestCheck flag indicates whether we need to call calculateSkipFalse
// to determine how many instructions to skip before checking for response packets or just skip to the last instruction (drop packet).
if skipRequestCheck {
inst = append(inst, bpf.JumpIf{Cond: bpf.JumpEqual, Val: srcAddrVal, SkipTrue: 0, SkipFalse: calculateSkipFalse(srcPort, dstPort)})
} else {
inst = append(inst, bpf.JumpIf{Cond: bpf.JumpEqual, Val: srcAddrVal, SkipTrue: 0, SkipFalse: size - curLen - uint8(len(inst)) - 2})
Expand Down Expand Up @@ -178,16 +185,15 @@ func compilePacketFilter(packetSpec *crdv1alpha1.Packet, srcIP, dstIP net.IP, di
}
}

// ip address and port check
inst = append(inst, loadIPv4SourceAddress)

if direction == crdv1alpha1.CaptureDirectionSourceToDestination {
inst = append(inst, compareIPPort(srcAddrVal, dstAddrVal, size, uint8(len(inst)), srcPort, dstPort, false)...)
inst = append(inst, compileIPPortFilter(srcAddrVal, dstAddrVal, size, uint8(len(inst)), srcPort, dstPort, false)...)
} else if direction == crdv1alpha1.CaptureDirectionDestinationToSource {
inst = append(inst, compareIPPort(dstAddrVal, srcAddrVal, size, uint8(len(inst)), dstPort, srcPort, false)...)
inst = append(inst, compileIPPortFilter(dstAddrVal, srcAddrVal, size, uint8(len(inst)), dstPort, srcPort, false)...)
} else {
inst = append(inst, compareIPPort(srcAddrVal, dstAddrVal, size, uint8(len(inst)), srcPort, dstPort, true)...)
inst = append(inst, compareIPPort(dstAddrVal, srcAddrVal, size, uint8(len(inst)), dstPort, srcPort, false)...)
inst = append(inst, compileIPPortFilter(srcAddrVal, dstAddrVal, size, uint8(len(inst)), srcPort, dstPort, true)...)
inst = append(inst, compileIPPortFilter(dstAddrVal, srcAddrVal, size, uint8(len(inst)), dstPort, srcPort, false)...)
}

// return (drop)
Expand Down Expand Up @@ -253,31 +259,31 @@ func compilePacketFilter(packetSpec *crdv1alpha1.Packet, srcIP, dstIP net.IP, di
// For simpler code generation in 'Both' direction, an extra instruction to accept the packet is added after instruction 014.
// The final instruction set looks like this:
// (000) ldh [12] # Load 2B at 12 (Ethertype)
// (001) jeq #0x800 jt 2 jf 27 # Ethertype: If IPv4, goto #2, else #26
// (001) jeq #0x800 jt 2 jf 27 # Ethertype: If IPv4, goto #2, else #27
// (002) ldb [23] # Load 1B at 23 (IPv4 Protocol)
// (003) jeq #0x6 jt 4 jf 27 # IPv4 Protocol: If TCP, goto #4, #26
// (003) jeq #0x6 jt 4 jf 27 # IPv4 Protocol: If TCP, goto #4, #27
// (004) ld [26] # Load 4B at 26 (source address)
// (005) jeq #0xaf40102 jt 6 jf 16 # If bytes match(10.244.1.2), goto #6, else #15
// (005) jeq #0xaf40102 jt 6 jf 16 # If bytes match(10.244.1.2), goto #6, else #16
// (006) ld [30] # Load 4B at 30 (dest address)
// (007) jeq #0xaf40103 jt 8 jf 27 # If bytes match(10.244.1.3), goto #8, else #26
// (007) jeq #0xaf40103 jt 8 jf 27 # If bytes match(10.244.1.3), goto #8, else #27
// (008) ldh [20] # Load 2B at 20 (13b Fragment Offset)
// (009) jset #0x1fff jt 27 jf 10 # Use 0x1fff as a mask for fragment offset; If fragment offset != 0, #10, else #26
// (009) jset #0x1fff jt 27 jf 10 # Use 0x1fff as a mask for fragment offset; If fragment offset != 0, #10, else #27
// (010) ldxb 4*([14]&0xf) # x = IP header length
// (011) ldh [x + 14] # Load 2B at x+14 (TCP Source Port)
// (012) jeq #0x7b jt 13 jf 27 # TCP Source Port: If 123, goto #13, else #26
// (012) jeq #0x7b jt 13 jf 27 # TCP Source Port: If 123, goto #13, else #27
// (013) ldh [x + 16] # Load 2B at x+16 (TCP dst port)
// (014) jeq #0x7c jt 15 jf 27 # TCP dst port: If 123, goto #15, else #26
// (014) jeq #0x7c jt 15 jf 27 # TCP dst port: If 123, goto #15, else #27
// (015) ret #262144 # MATCH
// (016) jeq #0xaf40103 jt 17 jf 27 # If bytes match(10.244.1.3), goto #16, else #26
// (016) jeq #0xaf40103 jt 17 jf 27 # If bytes match(10.244.1.3), goto #17, else #27
// (017) ld [30] # Load 4B at 30 (return traffic dest address)
// (018) jeq #0xaf40102 jt 19 jf 27 # If bytes match(10.244.1.2), goto #18, else #26
// (018) jeq #0xaf40102 jt 19 jf 27 # If bytes match(10.244.1.2), goto #19, else #27
// (019) ldh [20] # Load 2B at 20 (13b Fragment Offset)
// (020) jset #0x1fff jt 27 jf 21 # Use 0x1fff as a mask for fragment offset; If fragment offset != 0, #20, else #26
// (020) jset #0x1fff jt 27 jf 21 # Use 0x1fff as a mask for fragment offset; If fragment offset != 0, #21, else #27
// (021) ldxb 4*([14]&0xf) # x = IP header length
// (022) ldh [x + 14] # Load 2B at x+14 (TCP Source Port)
// (023) jeq #0x7c jt 24 jf 27 # TCP Source Port: If 124, goto #23, else #26
// (023) jeq #0x7c jt 24 jf 27 # TCP Source Port: If 124, goto #24, else #27
// (024) ldh [x + 16] # Load 2B at x+16 (TCP dst port)
// (025) jeq #0x7b jt 26 jf 27 # TCP dst port: If 123, goto #25, else #26
// (025) jeq #0x7b jt 26 jf 27 # TCP dst port: If 123, goto #26, else #27
// (026) ret #262144 # MATCH
// (027) ret #0 # NOMATCH

Expand Down
7 changes: 6 additions & 1 deletion pkg/agent/packetcapture/capture/bpf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestCalculateInstructionsSize(t *testing.T) {
},
},
count: 17,
direction: crdv1alpha1.CaptureDirectionSourceToDestination,
},
{
name: "proto and host and port and DestinationToSource",
Expand All @@ -77,7 +78,7 @@ func TestCalculateInstructionsSize(t *testing.T) {
},
},
},
count: 27,
count: 28,
direction: crdv1alpha1.CaptureDirectionBoth,
},
{
Expand All @@ -86,6 +87,7 @@ func TestCalculateInstructionsSize(t *testing.T) {
Protocol: &testTCPProtocol,
},
count: 10,
direction: crdv1alpha1.CaptureDirectionSourceToDestination,
},
{
name: "proto with src port",
Expand All @@ -98,6 +100,7 @@ func TestCalculateInstructionsSize(t *testing.T) {
},
},
count: 15,
direction: crdv1alpha1.CaptureDirectionSourceToDestination,
},
{
name: "proto with dst port",
Expand All @@ -110,12 +113,14 @@ func TestCalculateInstructionsSize(t *testing.T) {
},
},
count: 15,
direction: crdv1alpha1.CaptureDirectionSourceToDestination,
},

{
name: "any proto",
packet: &crdv1alpha1.Packet{},
count: 8,
direction: crdv1alpha1.CaptureDirectionSourceToDestination,
},
}

Expand Down

0 comments on commit d990beb

Please sign in to comment.