Platforms to show: All Mac Windows Linux Cross-Platform

/Network/Raw Socket/Raw Socket for UDP Protocol


Required plugins for this example: MBS Network Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Network/Raw Socket/Raw Socket for UDP Protocol

This example is the version from Sun, 23th Sep 2017.

Project "Raw Socket for UDP Protocol.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
End Class
Class MainWindow Inherits Window
Control Label1 Inherits Label
ControlInstance Label1 Inherits Label
End Control
Control iMessage Inherits TextField
ControlInstance iMessage Inherits TextField
EventHandler Sub TextChange() SendButton.Enabled = me.text.len > 0 End EventHandler
End Control
Control Label2 Inherits Label
ControlInstance Label2 Inherits Label
End Control
Control iIP Inherits TextField
ControlInstance iIP Inherits TextField
End Control
Control Label3 Inherits Label
ControlInstance Label3 Inherits Label
End Control
Control iPort Inherits TextField
ControlInstance iPort Inherits TextField
End Control
Control List Inherits Listbox
ControlInstance List Inherits Listbox
End Control
Control SendButton Inherits PushButton
ControlInstance SendButton Inherits PushButton
EventHandler Sub Action() dim Flags as integer = 0 dim r as Integer // port dim port as integer = val(iPort.Text) if port <= 0 or port >= 65535 then break MsgBox "Wrong port: "+iPort.Text Return end if // dest address ' UDP protocol header: 'struct udp_header '{ 'u_int32_t source_address; 'u_int32_t dest_address; 'u_int8_t placeholder; 'u_int8_t protocol; 'u_int16_t udp_length; '}; // IP Header 'struct iphdr { '__u8 ihl:4,version:4; '__u8 tos; '__be16 tot_len; '__be16 id; '__be16 frag_off; '__u8 ttl; '__u8 protocol; '__sum16 check; '__be32 saddr; '__be32 daddr; '/*The options start here. */ '}; 'struct udphdr '{ 'u_int16_t uh_sport; /* source port */ 'u_int16_t uh_dport; /* destination port */ 'u_int16_t uh_ulen; /* udp length */ 'u_int16_t uh_sum; /* udp checksum */ '}; // message dim m as string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // ConvertEncoding(iMessage.Text, encodings.UTF8) dim data as MemoryBlock = m // allocate memory dim udph as new MemoryBlock(8) dim iph as new MemoryBlock(20) // convert IPv4 from text to numeric value dim DestIP as Uint32 = RAWSocketMBS.inet_addr(iIP.Text) dim SourceIP as Uint32 = RAWSocketMBS.inet_addr("127.0.0.1") System.DebugLog "DestIP: &h"+hex(DestIP) System.DebugLog "SourceIP: &h"+hex(SourceIP) // create destination address for OS. This is for Mac! Windows and Linux have different structures dim dest as new MemoryBlock(16) #if TargetMacOS dest.UInt8Value(0) = dest.size dest.UInt8Value(1) = RAWSocketMBS.AddressFamilyINet dest.UInt16Value(2) = RAWSocketMBS.htons(port) dest.UInt32Value(4) = DestIP #else dest.UInt8Value(0) = RAWSocketMBS.AddressFamilyINet dest.UInt16Value(2) = RAWSocketMBS.htons(port) dest.UInt32Value(4) = DestIP #endif dim TotalLength as integer = (iph.size + data.size + udph.size) // Fill in the IP Header iph.UInt8Value(0) = &h45 // version (4) and Header length (5*4 bytes) iph.UInt8Value(1) = 0 // tos iph.UInt16Value(2) = TotalLength // total length iph.UInt16Value(4) = RAWSocketMBS.htons(54321) // packet ID iph.UInt16Value(6) = RAWSocketMBS.htons(0) iph.UInt8Value(8) = 255 iph.UInt8Value(9) = RAWSocketMBS.ProtocolUDP // 17 iph.UInt16Value(10) = 0 // Set to 0 before calculating checksum iph.UInt32Value(12) = SourceIP iph.UInt32Value(16) = DestIP // IP checksum dim ipData as MemoryBlock = iph + udph + data iph.UInt16Value(10) = RAWSocketMBS.CalcChecksum(ipData, ipData.size) System.DebugLog "checksum ip: &h"+ hex(iph.UInt16Value(10)) // UDP header udph.UInt16Value(0) = RAWSocketMBS.htons(port) // source port udph.UInt16Value(2) = RAWSocketMBS.htons(port) // dest port udph.UInt16Value(4) = RAWSocketMBS.htons(udph.size+data.size) // UDP header size + data size udph.UInt16Value(6) = 0 // leave checksum 0 now, filled later by pseudo header #if true then // Checksum optional // Now the UDP checksum using the pseudo header dim psh as new MemoryBlock(12) psh.UInt32Value(0) = SourceIP psh.UInt32Value(4) = DestIP psh.UInt8Value(8) = 0 psh.UInt8Value(9) = RAWSocketMBS.ProtocolUDP psh.UInt16Value(10) = RAWSocketMBS.htons(udph.size + data.size) dim pseudogram as MemoryBlock = psh + udph + data udph.UInt16Value(6) = RAWSocketMBS.CalcChecksum(pseudogram, pseudogram.size) System.DebugLog "checksum udp: &h"+ hex(udph.UInt16Value(6)) #endif dim DataToSend as MemoryBlock = iph + udph + data System.DebugLog "DataToSend: "+str(DataToSend.size) // send if dsock <> nil then r = dsock.SendTo(DataToSend, DataToSend.size, Flags, dest, dest.size) System.DebugLog "SendTo: "+str(r)+" "+str(dsock.Lasterror) end if iMessage.Text = "" End EventHandler
End Control
EventHandler Sub Close() ssock = nil dsock = nil End EventHandler
EventHandler Sub Open() // this example must be run as root to be allowed to use truely RAW Socket // Second, this app does not work. It does send, but we don't see results in the window. ChecksumTest // Create RAW Socket to send UDP ourselves dsock = new RAWSocketMBS(RAWSocketMBS.AddressFamilyINet, RAWSocketMBS.SocketTypeRaw, RAWSocketMBS.ProtocolRaw) // Create UDP socket to receive packets ssock = new MyRawSocket(RAWSocketMBS.AddressFamilyINet, RAWSocketMBS.SocketTypeDatagram, RAWSocketMBS.ProtocolUDP) if ssock.Lasterror <> 0 or ssock.Handle = -1 then MsgBox "Failed to create normal UDP socket"+EndOfLine+EndOfLine+"Error "+str(ssock.Lasterror) quit end if // to test receive, we bind to any address with given port // convert IPv4 from text to numeric value dim IP as Uint32 = 0 // all IPv4 // create destination address. This is for Mac! Windows and Linux have different structures dim dest as new MemoryBlock(16) #if TargetMacOS then dest.UInt8Value(0) = dest.size dest.UInt8Value(1) = RAWSocketMBS.AddressFamilyINet dest.UInt16Value(2) = RAWSocketMBS.htons(12345) dest.UInt32Value(4) = IP #else dest.UInt8Value(0) = RAWSocketMBS.AddressFamilyINet dest.UInt16Value(2) = RAWSocketMBS.htons(12345) dest.UInt32Value(4) = IP #endif if ssock.Bind(dest, dest.size) then log "Bind OK" else log "Bind: "+str(ssock.Lasterror) end if Exception r as UnsupportedOperationException MsgBox "Must be run as root!"+EndOfLine+EndOfLine+r.message quit End EventHandler
Shared Sub ChecksumTest() // some test packet dim s as string = decodehex("4500003c1c4640004006b1e6ac100a63ac100a0c") dim m as MemoryBlock = s dim checksum as integer = m.UInt16Value(10) m.UInt16Value(10) = 0 // for calculation dim calc as integer = RAWSocketMBS.CalcChecksum(m, m.size) if checksum <> calc then Break // plugin broken? end if End Sub
Sub log(s as string) List.AddRow s list.ScrollPosition = list.ScrollPosition + 1 End Sub
Property dsock As RAWSocketMBS
Property ssock As MyRawSocket
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
Class MyRawSocket Inherits RAWSocketMBS
EventHandler Sub DataAvailable() log CurrentMethodName // simply log what we read if false then // using ReadAll dim m as MemoryBlock = me.ReadAll dim s as string = DefineEncoding(m, encodings.UTF8) log s else // using ReadDatagram dim d as DatagramMBS = me.ReadDatagram dim s as string = DefineEncoding(d.Data, encodings.UTF8) log "Received: "+s log "from "+d.Address+":"+str(d.Port) end if End EventHandler
EventHandler Sub Error() log CurrentMethodName End EventHandler
EventHandler Sub SendComplete() log CurrentMethodName End EventHandler
Sub log(s as string) MainWindow.log s End Sub
End Class
End Project

See also:

The items on this page are in the following plugins: MBS Network Plugin.


The biggest plugin in space...