Search code examples
javasocketsparsingudpdatagram

Garbage output after parsing UDP packet


I am trying to extract information from a UDP packet but keep getting random output. Sometimes I get exactly what I want, and other times I don't.

Here is my code:

private static void receivePacket()
{
    try {
        DatagramSocket socket = new DatagramSocket(port);
        System.out.println("\n  Listening...");

        while(true)
        {
            // Create a packet
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);

            // Receive packet
            socket.receive(packet);
            byte[] data = packet.getData();

            // Parse the packet
            parse(data, packet.getLength());

            socket.send(packet);
         }

        } catch(Exception e) {
            e.printStackTrace();
        }
}

// Parse packets
private static void parse(byte [] data, int dataLength)
{
    ArrayList<String> name = new ArrayList<String>()
    String domain = "";

    // Get ID
    int id = ((data[0] & 0xff) << 8) + (data[1] & 0xff);
    System.out.println("\n  ID:\t\t" + id);

    // Get domain name and number of bits for each word in domain
    for(int i = 0; i < dataLength; i++)
    {
        // If the next bit is a letter then we know the current bit is the number of bits
        if((data[i] <= ' ') || (data[i] > '~'))
        {
            try {
                if((String.format("%c", data[i+1]).matches("^[a-zA-Z]$")))
                {
                    int dSize = Integer.parseInt(String.format("%d", data[i]));
                    name.add(Integer.toString(dSize));
                }

            } catch (Exception e) {
                //e.printStackTrace();
            }
        }
        else
        {
            // If current bit is letter add to ArrayList
            try {
                if((String.format("%c", data[i]).matches("^[a-zA-Z]$")))
                {
                    name.add(String.format("%c", data[i]));
                    domain += String.format("%c", data[i]);
                }

            } catch (Exception e) {
                //e.printStackTrace();
            }
        }
    }

    System.out.println("  Domain:\t" + domain);
    System.out.print("  Name:\t\t");
    name.add("0");

    for(int i = 0; i < name.size(); i++)
        System.out.print("\'" + name.get(i) + "\' ");

    System.out.println();
 }

I use the dig command dig @localhost -p 1299 test.mydomain.abc to send a UDP packet to the server. Here is my output after running it six times. The output each time should be the following (ID will vary):

ID:           64666
Domain:       testmydomainabc
Name:         '4' 't' 'e' 's' 't' '8' 'm' 'y' 'd' 'o' 'm' 'a' 'i' 'n' '3' 'a' 'b' 'c' '0'

However, it is not as you see here starting from run #4: enter image description here

It is completely random and I don't understand why. I am coding this on Java and Windows 10. Any help will be appreciated, thank you!

Raw Data:

Successful trial: '4' 't' 'e' 's' 't' '8' 'm' 'y' 'd' 'o' 'm' 'a' 'i' 'n' '3' 'a' 'b' 'c' '0'

b7 01 20 00 01 00 00 00 00 00 01 04 t e s t 08 m y d o m a i n 03 a b c 00 00 01 00 01 00 00 ) 10 00 00 00 00 00 00 00

Unsuccessful: '-127' 'f' '4' 't' 'e' 's' 't' '8' 'm' 'y' 'd' 'o' 'm' 'a' 'i' 'n' '3' 'a' 'b' 'c' '0'

81 f 01 20 00 01 00 00 00 00 00 01 04 t e s t 08 m y d o m a i n 03 a b c 00 00 01 00 01 00 00 ) 10 00 00 00 00 00 00 00


Solution

  • Your loop in parse starts from 0, should probably start from 2. Otherwise the ID bytes will be included in the Domain parsing (or throw an exception that are silenty ignored)