B4J Question Having Trouble Extracting Fields From UDP Packet (NetFlow Protocol)

mollensoft

Member
Licensed User
Longtime User
Hello All,
I have a project where I need to receive Netflow V5 Packets and extract the Source and Destination IP Addresses inside the PDUs - I'm using B4J on Windows 10

Problem: Extracting the Netflow packet Header fields seems to work okay but when I get to the PDUs I cannot find the Source and Destination Addresses which should start on Byte 24.

Below is part of the code I'm using to extract the fields from the Packet - have been stuck on this for a while and would appreciate any recommendations (Attached is the Netflow V5 Packet structure for easy reference)

B4X:
Sub Process_Globals
    Dim UDPSocket1 As UDPSocket
End Sub

Sub AppStart (Args() As String)
    UDPSocket1.Initialize("UDP", 2055, 10000)
    StartMessageLoop
End Sub


Sub UDP_PacketArrived (Packet As UDPPacket)
    
    Dim msg As String
    'msg = BytesToString(Packet.Data, Packet.Offset, Packet.Length, "ASCII")
    Log("Message received: " & msg)
    Log("PACKET LENGTH:" & Packet.Length)
    Log("PACKET OFFSET:" & Packet.Offset)
    Log("PACKET STRING:" & Packet.toString)
        
    '''''''''''
    Dim raf As RandomAccessFile
    raf.Initialize3(Packet.Data, False)
    
    Dim versionnumber As Short  
    versionnumber = raf.readshort(0)
    Log("versionnumber: " & versionnumber)   'this works ok

    Dim pducount As Short 
    pducount = raf.ReadShort(2)
    Log("pducount: " & pducount)  'this works ok

    Dim sysuptime As Int  
    sysuptime = raf.ReadInt(4)
    Log("sysuptime: " & sysuptime)  'this works ok
    
    Dim unix_secs As Int  
    unix_secs = raf.readint(8)
    Log("unix_secs: " & unix_secs)  'this works ok
    
    Dim unix_nsecs As Int  
    unix_nsecs = raf.readint(12)
    Log("unix_nsecs: " & unix_nsecs)  'this works ok
    
    Dim flowseq As Int  
    flowseq = raf.readint(16)
    Log("flowseq: " & flowseq)  'this works ok
    
    Dim eng_type As Int  
    eng_type = raf.ReadShort(20)
    Log("eng_type: " & eng_type)  'this works ok
    
    Dim eng_id As Char  
    eng_id = raf.ReadShort(21)
    Log("eng_id: " & eng_id)  'this works ok
    
    Dim samp_interval As Short  
    samp_interval = raf.ReadShort(22)
    Log("samp_interval: " & samp_interval)  'this works ok
    
    Log("End of Header, Begin First PDU")
    
    Dim SrcIP As Int   'This Does Not Work cannot seem to read IP Address (in decimal)
    SrcIP = raf.readint(24) 'Have tried reading from multiple locations - none seem to produce the IP Address
    Log("SrcIP: " & SrcIP)
    
    Dim DstIP As Int   'This Does Not Work cannot seem to read IP Address (in decimal)
    SrcIP = raf.readint(28) 'Have tried reading from multiple locations - none seem to produce the IP Address
    Log("DstIP: " & DstIP)
    
    Log("End Of First PDU")
    
    'process subsequent PDUs with a loop
    
End Sub
 

Attachments

  • NetFlowByteMask.JPG
    NetFlowByteMask.JPG
    133.1 KB · Views: 222

Daestrum

Expert
Licensed User
Longtime User
Are you checking pducount is non-zero?
Also the ip address won't be an int it will be 4 unsigned bytes, 1 for each part of the ip address.
 
Upvote 0

mollensoft

Member
Licensed User
Longtime User
Hi Daestrum, Thank you, Yes I am checking for that.

I am using wireshark to view the UDP Packets as they are received so I can compare the packet contents between wireshark and what the B4J app is receiving/printing to log console.

The interesting thing is, occasionally, I do See the Correct IP Address beginning at Byte 24 which makes me think the way I'm reading the 4 Bytes (24,25,26 & 27) using RandomAccessFile library is wrong. Inconsistent results is puzzling. But Reading the flowseq field in the header seems to work correctly which is how I'm able to correlate between wireshark Packets and the B4J App.

-Alan
 
Upvote 0

mollensoft

Member
Licensed User
Longtime User
I figured out the issue - some of the bytes are signed thus cannot be a part of an IPV4 address so they must be converted to unsigned bytes: below is subroutine I found elsewhere on the site that helped solve the problem in case others get here looking for a similar problem. I don't fully understand the typing in B4J but will spend some type on this in the future.

Apparently this is a type issue in B4J related to its roots in Java

send the subroutine an signed byte and it will return an unsigned byte (perfect for ipv4 addressing)

B4X:
Sub ConvertSignedByteToUnsigned(b As Byte) As Int
   Return Bit.And(b, 0xFF)
End Sub
 
Upvote 0
Top