Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct UDP packet but not send it

This is sort of an odd request.

I have a byte array that I need to send over serial port to another device using C#. However I need to first wrap the byte array within a udp packet, but again, it's going to be sent via serial port, not via udp. Is there a way to construct a udp packet as an array of bytes to then send over the serial port?

I've sent and received messages using udp before but never where the udp packet is constructed but not sent via udp.

like image 959
Justin Avatar asked May 25 '11 14:05

Justin


People also ask

Does UDP send a response packet?

UDP is completely stateless, so after firing off a packet the only way an application can expect a response is if it knows the other end is going to send one.

Does UDP require a response?

Now, since UDP is a connection-less protocol so unlike TCP, UDP server will not send response over some connection, instead, UDP server will extract the source IP address and source port from the request and send the response back to client.

Does UDP send packets in order?

The communication protocol just sends the packets, which means it has much lower bandwidth overhead and latency. With UDP, packets may take different paths between sender and receiver. As a result, some packets may be lost or received out of order.

Does UDP guarantee in order delivery?

UDP does not guarantee that transmitted packets will be received in any particular order, although the underlying protocols such as IP imply that packets will generally be received in the order transmitted in the absence of routing and/or hardware errors. TCP places no limits on the size of transmitted data.


2 Answers

C# Raw UDP Socket Program Example

like image 145
Yochai Timmer Avatar answered Sep 23 '22 11:09

Yochai Timmer


I'm going to accept Yochai's answer, as that link (and other pages within that site) provided the code to build both the udp packet and the ip header. For others trying to accomplish it, here is the code:

How to call it:

var udpPacketBytes = UDPPacket.Construct(IPAddress.Parse("1.1.1.1"), 1000, IPAddress.Parse("2.2.2.2"), 6100, payloadBytes);

UDPPacket class:

public static class UDPPacket
    {
        public static byte[] Construct(IPAddress sourceAddress, ushort sourcePort, IPAddress destinationAddress, ushort destinationPort, byte[] payload)
        {
            var bindAddress = IPAddress.Any;

            // Make sure parameters are consistent
            //if ((sourceAddress.AddressFamily != destinationAddress.AddressFamily) || (sourceAddress.AddressFamily != bindAddress.AddressFamily))
            //{
            //    throw new Exception("Source and destination address families don't match!");
            //}

            // Start building the headers
            byte[] builtPacket;
            UdpHeader udpPacket = new UdpHeader();
            ArrayList headerList = new ArrayList();
            //Socket rawSocket = null;
            //SocketOptionLevel socketLevel = SocketOptionLevel.IP;

            // Fill out the UDP header first
            Console.WriteLine("Filling out the UDP header...");
            udpPacket.SourcePort = sourcePort;
            udpPacket.DestinationPort = destinationPort;
            udpPacket.Length = (ushort)(UdpHeader.UdpHeaderLength + payload.Length);
            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 + payload.Length);
                ipv4Packet.SourceAddress = sourceAddress;
                ipv4Packet.DestinationAddress = destinationAddress;

                // 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 = destinationAddress;

                // 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...");
                int rc = rawSocket.SendTo(builtPacket, new IPEndPoint(destinationAddress, destinationPort));
                Console.WriteLine("send {0} bytes to {1}", rc, destinationAddress.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();
            }
            */

            return builtPacket;
        }
    }

Protocol classes: (too long to post here)

Protocol Class Code

like image 32
Justin Avatar answered Sep 22 '22 11:09

Justin