< C++ Raw UDP Socket Program Example | Main | C# Raw Socket Ping Program Example >


 

Chapter 8 Part 19:

Client (and Server) Sockets Communication

 

 

What do we have in this chapter 8 Part 19?

  1. C# Raw UDP Socket Program Example

 

C# Raw UDP Socket Program Example

 

Create a new console application project and you might use the project and solution names as shown in the following Figure.

 

C# Raw UDP Socket Program Example - creating a new console application project in Visual Studio 2008

 

Next, rename the class to RawUDP by renaming the source file just to reflect our application.

 

C# Raw UDP Socket Program Example - renaming the source file

 

Add/edit the following using directives at the top of the file.

 

using System;

using System.Net;

using System.Net.Sockets;

using System.Collections;

// Reference the protocol header classes

using ProtocolHeaderDefinition;

 

Inside the RawUDP class adds the following usage() method.

 

static void usage()

{

            Console.WriteLine("Usage: Executable_file_name [-as source-addr] [-ad dest-addr] [-ps source-port]");

            Console.WriteLine("                  [-pd dest-port] [-x payload-size] [-n send-count] [-b bind-addr]");

            Console.WriteLine(" Options");

            Console.WriteLine("     -as source-addr     Source address for IP packet");

            Console.WriteLine("     -ad dest-addr       Destination address for IP packet");

            Console.WriteLine("     -ps source-port     Source port for UDP packet");

            Console.WriteLine("     -pd dest-port       Destination port for UDP packet");

            Console.WriteLine("     -b  bind-addr       Local address to bind raw socket to");

            Console.WriteLine("     -x  payload-size    Number of bytes for UDP payload");

            Console.WriteLine("     -n  send-count      Number of times to send packet");

            Console.WriteLine("....Else default values will be used...");

}

 

 

 

 

Next, add the Main() code.

 

static void Main(string[ ] args)

        {

            // Default/initial values, the source should be a spoofed IP :-)

            IPAddress   sourceAddress = IPAddress.Parse( "1.1.1.1" ),

            destAddress   = IPAddress.Parse( "2.2.2.2" ),

            bindAddress   = IPAddress.Any;

            ushort      sourcePort = 5150,

            destPort   = 1234;

            int         messageSize = 16,

            sendCount   = 5;

 

            usage();

            Console.WriteLine();

 

        // Parse the command line

        for(int i=0; i < args.Length ;i++)

        {

            try

            {

                if ( ( args[i][0] == '-' ) || ( args[i][0] == '/' ) )

                {

                    switch ( Char.ToLower( args[i][1] ) )

                    {

                        case 'a':

                            // Address parameter: source or destination

                            if ( Char.ToLower( args[i][2] ) == 's' )

                            {

                                sourceAddress = IPAddress.Parse( args[ ++i ].ToString() );

                            }

                            else if ( Char.ToLower( args[i][2] ) == 'd' )

                            {

                                destAddress = IPAddress.Parse( args[ ++i ].ToString() );

                            }

                            else

                            {

                                usage();

                                return;

                            }

                            break;

                        case 'b':

                            // Local address to bind the socket to

                            bindAddress = IPAddress.Parse( args[ ++i ].ToString() );

                            break;

                        case 'p':

                            // Port parameter: source or destination

                            if ( Char.ToLower( args[i][2] ) == 's' )

                            {

                                sourcePort = System.Convert.ToUInt16( args[ ++i ].ToString() );

                            }

                            else if ( Char.ToLower( args[i][2] ) == 'd' )

                            {

                                destPort = System.Convert.ToUInt16( args[ ++i ].ToString() );

                            }

                            else

                            {

                                usage();

                                return;

                            }

                            break;

                        case 'x':

                            // Size of message to send

                            messageSize = System.Convert.ToInt32( args[ ++i ].ToString() );

                            break;

                        case 'n':

                            // Number of times to send message

                            sendCount = System.Convert.ToInt32( args[ ++i ].ToString() );

                            break;

                        default:

                            usage();

                            return;

                    }

                }

            }

            catch

            {

                usage();

                return;

            }

        }

 

        // Make sure parameters are consistent

        if ( ( sourceAddress.AddressFamily != destAddress.AddressFamily ) || ( sourceAddress.AddressFamily != bindAddress.AddressFamily) )

        {

            Console.WriteLine("Source and destination address families don't match!");

            usage();

            return;

        }

 

        // Print the command line parameters

        Console.WriteLine("Source address : {0}   \tPort: {1}", sourceAddress.ToString(), sourcePort.ToString() );

        Console.WriteLine("Dest   address : {0}   \tPort: {1}", destAddress.ToString(), destPort.ToString() );

        Console.WriteLine("Local interface: {0}", bindAddress.ToString() );

        Console.WriteLine("Message size   : {0}", messageSize);

        Console.WriteLine("Send count     : {0}", sendCount);

 

        // Start building the headers

        Console.WriteLine("Building the packet header...");

        byte [ ]             builtPacket, payLoad = new byte [ messageSize ];

        UdpHeader           udpPacket = new UdpHeader();

        ArrayList           headerList = new ArrayList();

        Socket              rawSocket = null;

        SocketOptionLevel   socketLevel = SocketOptionLevel.IP;

 

        // Initialize the payload

        Console.WriteLine("Initialize the payload...");

        for(int i=0; i < payLoad.Length ;i++)

            payLoad[i] = (byte) '#';

 

        // Fill out the UDP header first

        Console.WriteLine("Filling out the UDP header...");

        udpPacket.SourcePort        = sourcePort;

        udpPacket.DestinationPort   = destPort;

        udpPacket.Length            = (ushort) (UdpHeader.UdpHeaderLength + messageSize);

        udpPacket.Checksum          = 0;

 

        if ( sourceAddress.AddressFamily == AddressFamily.InterNetwork )

        {

            Ipv4Header      ipv4Packet = new Ipv4Header();

 

            // Build the IPv4 header

            Console.WriteLine("Building the IPv4 header...");

            ipv4Packet.Version      = 4;

            ipv4Packet.Protocol     = (byte) ProtocolType.Udp;

            ipv4Packet.Ttl          = 2;

            ipv4Packet.Offset       = 0;

            ipv4Packet.Length       = (byte) Ipv4Header.Ipv4HeaderLength;

            ipv4Packet.TotalLength  = (ushort) System.Convert.ToUInt16( Ipv4Header.Ipv4HeaderLength + UdpHeader.UdpHeaderLength + messageSize );

            ipv4Packet.SourceAddress        = sourceAddress;

            ipv4Packet.DestinationAddress   = destAddress;

 

            // Set the IPv4 header in the UDP header since it is required to calculate the

            //    pseudo header checksum

            Console.WriteLine("Setting the IPv4 header for pseudo header checksum...");

            udpPacket.ipv4PacketHeader = ipv4Packet;

 

            // Add IPv4 header to list of headers -- headers should be added in th order

            //    they appear in the packet (i.e. IP first then UDP)

            Console.WriteLine("Adding the IPv4 header to the list of header, encapsulating packet...");

            headerList.Add( ipv4Packet );

            socketLevel = SocketOptionLevel.IP;

        }

        else if ( sourceAddress.AddressFamily == AddressFamily.InterNetworkV6 )

        {

            Ipv6Header      ipv6Packet = new Ipv6Header();

 

            // Build the IPv6 header

            Console.WriteLine("Building the IPv6 header...");

            ipv6Packet.Version          = 6;

            ipv6Packet.TrafficClass     = 1;

            ipv6Packet.Flow             = 2;

            ipv6Packet.HopLimit         = 2;

            ipv6Packet.NextHeader       = (byte) ProtocolType.Udp;

            ipv6Packet.PayloadLength    = (ushort) ( UdpHeader.UdpHeaderLength + payLoad.Length );

            ipv6Packet.SourceAddress        = sourceAddress;

            ipv6Packet.DestinationAddress   = destAddress;

 

            // Set the IPv6 header in the UDP header since it is required to calculate the

            //    pseudo header checksum

            Console.WriteLine("Setting the IPv6 header for pseudo header checksum...");

            udpPacket.ipv6PacketHeader = ipv6Packet;

 

            // Add the IPv6 header to the list of headers - headers should be added in the order

            //    they appear in the packet (i.e. IP first then UDP)

            Console.WriteLine("Adding the IPv6 header to the list of header, encapsulating packet...");

            headerList.Add( ipv6Packet );

            socketLevel = SocketOptionLevel.IPv6;

        }

 

        // Add the UDP header to list of headers after the IP header has been added

        Console.WriteLine("Adding the UDP header to the list of header, after IP header...");

        headerList.Add( udpPacket );

 

        // Convert the header classes into the binary on-the-wire representation

        Console.WriteLine("Converting the header classes into the binary...");

        builtPacket = udpPacket.BuildPacket( headerList, payLoad );

 

        // Create the raw socket for this packet

        Console.WriteLine("Creating the raw socket using Socket()...");

        rawSocket = new Socket(sourceAddress.AddressFamily, SocketType.Raw, ProtocolType.Udp);

 

        // Bind the socket to the interface specified

        Console.WriteLine("Binding the socket to the specified interface using Bind()...");

        rawSocket.Bind( new IPEndPoint( bindAddress, 0 ) );

 

        // Set the HeaderIncluded option since we include the IP header

        Console.WriteLine("Setting the HeaderIncluded option for IP header...");

        rawSocket.SetSocketOption( socketLevel, SocketOptionName.HeaderIncluded, 1 );

        try

        {

            // Send the packet!

            Console.WriteLine("Sending the packet...");

            for (int i = 0; i < sendCount; i++)

            {

                int rc = rawSocket.SendTo(builtPacket, new IPEndPoint(destAddress, destPort));

                Console.WriteLine("send {0} bytes to {1}", rc, destAddress.ToString());

            }

        }

        catch (SocketException err)

        {

            Console.WriteLine("Socket error occurred: {0}", err.Message);

            // http://msdn.microsoft.com/en-us/library/ms740668.aspx

        }

        finally

        {

            // Close the socket

            Console.WriteLine("Closing the socket...");

            rawSocket.Close();

        }

    }

 

We need to add references to the Protocol.cs so that all the definition defined in the ProtocolHeaderDefinition can be resolved.

 

C# Raw UDP Socket Program Example - unresolved header highlighted in the editor

 

Select the project folder > Right click mouse > Select Add context menu > Select Existing Item context menu.

 

C# Raw UDP Socket Program Example - adding a new existing item into existing project

 

Browse and find the Protocol.cs file created previously. Select the file and click Add.

 

C# Raw UDP Socket Program Example - browsing and finding the Protocol.cs source file

 

Now, you can see the Protocol.cs file is included under the project folder as shown in the following Figure.

 

C# Raw UDP Socket Program Example - building the project

 

Next, build the project and make sure there is no error.

Then, run the project. Any error will be thrown by the exception handlers.

 

C# Raw UDP Socket Program Example - running the project

 

 

 

 

The following is the sample output.

 

C# Raw UDP Socket Program Example - a sample output with default argument values

 

The following is a sample output when run from the command prompt in the private network with 192.168.1.0 domain.

 

C# Raw UDP Socket Program Example - running the program from command line with arguments supplied

 


< C++ Raw UDP Socket Program Example | Main | C# Raw Socket Ping Program Example >