Need help with EthernetUDP on DNS script

I have been attempting to get this fake DNS server to function within my Hamnet mesh network to point to my NTP server. For days I thought it was the NTP server failing to respond until I finally did some packet sniffing with WireShark. The problem appears to be that the return address for the NTP server from the DNS server is being truncated as it is the last part of the returned packet to a DNS request.

This is using an UNO R3 with an Arduino ethernet shield. When I debug print the responseBuffer after ending the UDP write, everything is there! So maybe someone has some idea why the sent responseBuffer truncates the IP address.

Thanks

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

// setting for EthernetShield
byte mac[] = {
  0x74, 0xE5, 0x43, 0xE8, 0xCE, 0xFC};
byte ip[] = { // IP of DNS Server
  10, 87, 28, 146};

byte resIp[] = { // IP response
  10, 87, 28, 147};

unsigned int listenPort = 53;
IPAddress remoteIp;
unsigned int remotePort;
EthernetUDP Udp; // An Ethernet UDP instance 
#define PACKET_MAX_SIZE 512

char requestBuffer[PACKET_MAX_SIZE];
char responseBuffer[PACKET_MAX_SIZE];
String readString;

void setup() {
  Ethernet.begin(mac, ip);
  Udp.begin(listenPort);
  Serial.begin(19200);
}

void loop() {
  int requestSize = Udp.parsePacket();
  if(requestSize) {
    Udp.read(requestBuffer, PACKET_MAX_SIZE);
    remoteIp = Udp.remoteIP();
    remotePort = Udp.remotePort();

    int type = (requestBuffer[2] >> 3) & 15;
    if(type == 0) { // Standard Query
      readString = "";
      int ini = 12;
      int lon = requestBuffer[ini];
      char domain[64];
      int i = 0;
      while(lon != 0) {
        for(int j = 0; j < lon; j++) {
          domain[i++] = requestBuffer[ini + j + 1];
          readString += requestBuffer[ini + j + 1];
        }
        domain[i++] = '.';
        ini += lon + 1;
        lon = requestBuffer[ini];
      }
      domain[i] = '\0';
      if(readString.indexOf('us pool ntp') > 0) { // NTP request exists
        Serial.print(remoteIp);
        Serial.print("  ");
        Serial.println(domain);
        int resIndex = 0;
        for(int k = 0; k < 2; k++) { // identification
          responseBuffer[resIndex++] = requestBuffer[k];
        }
        responseBuffer[resIndex++] = '\x81'; // response
        // recursion desired
        responseBuffer[resIndex++] = '\x80'; // recursive
        // no error
        for(int k = 4; k < 6; k++) { // question
          responseBuffer[resIndex++] = requestBuffer[k];
        }
        for(int k = 4; k < 6; k++) { // answer
          responseBuffer[resIndex++] = requestBuffer[k];
        }
        for(int k = 0; k < 4; k++) { // authority, addition
          responseBuffer[resIndex++] = '\x00';
        }
        for(int k = 12; k < requestSize - 8; k++) { // question
          responseBuffer[resIndex++] = requestBuffer[k];
        }
        responseBuffer[resIndex++] = '\xc0'; // Offset to domain name
        responseBuffer[resIndex++] = '\x0c';
        responseBuffer[resIndex++] = '\x00'; // type
        responseBuffer[resIndex++] = '\x01';
        responseBuffer[resIndex++] = '\x00'; // class
        responseBuffer[resIndex++] = '\x01';
        responseBuffer[resIndex++] = '\x00'; // ttl
        responseBuffer[resIndex++] = '\x00';
        responseBuffer[resIndex++] = '\x00';
        responseBuffer[resIndex++] = '\x3c';
        responseBuffer[resIndex++] = '\x00'; // ip length
        responseBuffer[resIndex++] = '\x04';
        responseBuffer[resIndex++] = resIp[0]; // ip
        responseBuffer[resIndex++] = resIp[1];
        responseBuffer[resIndex++] = resIp[2];
        responseBuffer[resIndex++] = resIp[3];
        responseBuffer[resIndex++] = '\x00'; // end
        Udp.beginPacket(remoteIp, remotePort);
        Udp.write((uint8_t *)responseBuffer, (uint8_t)(resIndex-1));
        Udp.endPacket();
      }
    }
  }
  // delay(10);
}

It looks like every 0.2 seconds your Arduino is trying to get the MAC address of the gateway router (10.87.28.1). I suspect it is stuck in the Ethernet.begin() function. Is that the right IP address for your gateway router? If not you should add a few more arguments to Ethernet.begin() to specify and DNS Server and Gateway Router addresses.

Thanks John, you're definitely onto something there but it seems that the only way around the problem is to have a gateway with the last octet being a '1'. Unfortunately, the gateway is 10.87.28.145 (assigned by a firmware algo) so the DNS server IP is 10.87.28.146. It's late and I've been beating my head against the wall with this all day, so maybe I should just sleep on it...

If you don't specify an IP address Ethernet.begin() will use DHCP to get IP, Gateway Router, and DNS Server addresses.

If you DO specify your IP address as AA.BB.CC.DD but don't specify a Gateway Router or DNS Server address they will default to AA.BB.CC.1. If those default address are not correct you have to put the Gateway Router address into your Ethernet.begin(). You can use it for both the Gateway Router and DNS Server:

byte gateway[] = {10, 87, 28, 145}; // IP of Gateway Router

    Ethernet.begin(mac, ip, gateway, gateway);

Thank you very much John, it is up and responding properly with the NTP server address now!!! No wonder you have over 10,000 posts... you know what you're doing!

Thanks again!