Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Files at this revision

API Documentation at this revision

Comitter:
andrewboyson
Date:
Sun Jan 24 15:09:55 2021 +0000
Parent:
192:0dfa138a8e7d
Child:
194:f35c6e218de1
Commit message:
Fixed ability of name resolution to use IPv6 - the MAC for the DNS server IP address had to be made available.

Changed in this revision

ip4/ip4addr.c Show annotated file Show diff for this revision Revisions of this file
ip6/ip6addr.c Show annotated file Show diff for this revision Revisions of this file
ip6/ip6addr.h Show annotated file Show diff for this revision Revisions of this file
resolve/ar4.c Show annotated file Show diff for this revision Revisions of this file
resolve/ar4.h Show annotated file Show diff for this revision Revisions of this file
resolve/ar6.c Show annotated file Show diff for this revision Revisions of this file
resolve/ar6.h Show annotated file Show diff for this revision Revisions of this file
resolve/nr.c Show annotated file Show diff for this revision Revisions of this file
resolve/nr.h Show annotated file Show diff for this revision Revisions of this file
resolve/nrtest.c Show annotated file Show diff for this revision Revisions of this file
resolve/nrtest.h Show annotated file Show diff for this revision Revisions of this file
udp/dns/dnsquery.c Show annotated file Show diff for this revision Revisions of this file
--- a/ip4/ip4addr.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/ip4/ip4addr.c	Sun Jan 24 15:09:55 2021 +0000
@@ -34,13 +34,41 @@
     return HttpAddF("%d.%d.%d.%d", a3, a2, a1, a0); 
 }
 
-uint32_t Ip4AddrParse(const char* text)
+uint32_t Ip4AddrParse(const char* pText) //Returns 0 on error
 {
+    const char* p = pText;
     int ints[4];
-    sscanf(text, "%d.%d.%d.%d", &ints[3], &ints[2], &ints[1], &ints[0]);
-    return (ints[0] << 24) + (ints[1] << 16) + (ints[2] << 8) + ints[3];
+    int field = 0;
+    int word = 0;
+    while(true)
+    {
+        switch (*p)
+        {
+            case '.':
+                ints[field] = word;
+                field++;
+                if (field > 3) return 0;
+                word = 0;
+                break;
+            case '0': word *= 10; word += 0; break;
+            case '1': word *= 10; word += 1; break;
+            case '2': word *= 10; word += 2; break;
+            case '3': word *= 10; word += 3; break;
+            case '4': word *= 10; word += 4; break;
+            case '5': word *= 10; word += 5; break;
+            case '6': word *= 10; word += 6; break;
+            case '7': word *= 10; word += 7; break;
+            case '8': word *= 10; word += 8; break;
+            case '9': word *= 10; word += 9; break;
+            case 0:
+                ints[field] = word;
+                uint32_t addr4 = (ints[0] << 0) + (ints[1] << 8) + (ints[2] << 16) + (ints[3] << 24);
+                return addr4;
+            default: return 0;
+        }
+        p++;
+    }
 }
-
 void Ip4AddrFromDest(const int dest, uint32_t* pDstIp)
 {
     switch (dest)
--- a/ip6/ip6addr.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/ip6/ip6addr.c	Sun Jan 24 15:09:55 2021 +0000
@@ -54,6 +54,58 @@
     *p = 0;
     return p - pText;
 }
+void Ip6AddrParse(const char *pText, char *address) //Contains an empty address if invalid
+{
+    int field = 0;
+    int word = 0;
+    while(true)
+    {
+        switch (*pText)
+        {
+            case ':':
+                address[field] = (word >> 8) & 0xFF;
+                field++;
+                if (field > 15) { address[0] = 0; return; }
+                address[field] = word & 0xFF;
+                field++;
+                if (field > 15) { address[0] = 0; return; }
+                word = 0;
+                break;
+            case '0': word <<= 4; word |= 0; break;
+            case '1': word <<= 4; word |= 1; break;
+            case '2': word <<= 4; word |= 2; break;
+            case '3': word <<= 4; word |= 3; break;
+            case '4': word <<= 4; word |= 4; break;
+            case '5': word <<= 4; word |= 5; break;
+            case '6': word <<= 4; word |= 6; break;
+            case '7': word <<= 4; word |= 7; break;
+            case '8': word <<= 4; word |= 8; break;
+            case '9': word <<= 4; word |= 9; break;
+            case 'a':
+            case 'A': word <<= 4; word |= 10; break;
+            case 'b':
+            case 'B': word <<= 4; word |= 11; break;
+            case 'c':
+            case 'C': word <<= 4; word |= 12; break;
+            case 'd':
+            case 'D': word <<= 4; word |= 13; break;
+            case 'e':
+            case 'E': word <<= 4; word |= 14; break;
+            case 'f':
+            case 'F': word <<= 4; word |= 15; break;
+            case 0:
+                address[field] = (word >> 8) & 0xFF;
+                field++;
+                if (field != 15) { address[0] = 0; return; }
+                address[field] = word & 0xFF;
+                return;
+            default: 
+                address[0] = 0;
+                return;
+        }
+        pText++;
+    }
+}
 static void logHexNibble(bool* pAdded, int number, int index)
 {
     int nibble = number;
--- a/ip6/ip6addr.h	Fri Jan 22 13:24:08 2021 +0000
+++ b/ip6/ip6addr.h	Sun Jan 24 15:09:55 2021 +0000
@@ -2,6 +2,7 @@
 #include <stdbool.h>
 
 extern int  Ip6AddrToString(const char* ip, int size, char* text);
+extern void Ip6AddrParse   (const char *ip, char *address);
 extern int  Ip6AddrLog     (const char* ip);
 extern int  Ip6AddrHttp    (const char* ip);
 
--- a/resolve/ar4.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/ar4.c	Sun Jan 24 15:09:55 2021 +0000
@@ -152,6 +152,15 @@
     }
     return false;
 }
+bool Ar4CheckHaveMacAndFetchIfNot(uint32_t ip)
+{
+    if (!Ar4HaveMacForIp(ip))
+    {
+        Ar4MakeRequestForMacFromIp(ip); //The request is only repeated if made after a freeze time - call as often as you want.
+        return false;
+    }
+    return true;
+}
 uint32_t Ar4IndexToIp(int i)
 {
     return records[i].ip;
--- a/resolve/ar4.h	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/ar4.h	Sun Jan 24 15:09:55 2021 +0000
@@ -10,6 +10,7 @@
 extern void     Ar4IpToMac(uint32_t ip, char* pMac);
 extern uint32_t Ar4IndexToIp(int index);
 extern bool     Ar4HaveMacForIp(uint32_t ip);
+extern bool     Ar4CheckHaveMacAndFetchIfNot(uint32_t ip);
 
 extern void     Ar4SendHttp(void);
 extern void     Ar4SendAjax(void);
--- a/resolve/ar6.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/ar6.c	Sun Jan 24 15:09:55 2021 +0000
@@ -145,7 +145,7 @@
     }
     MacClear(mac);
 }
-bool Ar6HaveMacForIp(char* ip, char* mac)
+bool Ar6HaveMacForIp(char* ip)
 {
     for (int i = 0; i < RECORDS_COUNT; i++)
     {
@@ -153,6 +153,15 @@
     }
     return false;
 }
+bool Ar6CheckHaveMacAndFetchIfNot(char* ip)
+{
+    if (!Ar6HaveMacForIp(ip))
+    {
+        Ar6MakeRequestForMacFromIp(ip); //The request is only repeated if made after a freeze time - call as often as you want.
+        return false;
+    }
+    return true;
+}
 void Ar6IndexToIp(int i, char* ip)
 {
     Ip6AddrCopy(ip, records[i].ip);
--- a/resolve/ar6.h	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/ar6.h	Sun Jan 24 15:09:55 2021 +0000
@@ -8,7 +8,8 @@
 
 extern void Ar6IpToMac(char* ip, char* pMac);
 extern void Ar6IndexToIp(int index, char* pIp);
-extern bool Ar6HaveMacForIp(char* ip, char* mac);
+extern bool Ar6HaveMacForIp(char* ip);
+extern bool Ar6CheckHaveMacAndFetchIfNot(char* ip);
 
 extern void Ar6SendHttp(void);
 extern void Ar6SendAjax(void);
--- a/resolve/nr.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/nr.c	Sun Jan 24 15:09:55 2021 +0000
@@ -17,6 +17,7 @@
 #include       "nr.h"
 #include   "nrtest.h"
 #include      "ndp.h"
+#include      "ar6.h"
 
 bool Nr4Trace = false; //Do not use
 bool NrTrace = false;
@@ -540,7 +541,7 @@
 
 static void sendRequest(struct record* pr)
 {
-    if (DnsQueryIsBusy) return;
+    //if (DnsQueryIsBusy) return;
     
     switch (pr->state)
     {
@@ -581,7 +582,7 @@
             break;
         case STATE_WAIT_FOR_ETH:
             if (!DnsQueryIsBusy)
-            {
+            {   
                 switch (pr->todo)
                 {
                     case TODO_NAME_FROM_ADDRESS: queryNameFromIp(pr); break;
--- a/resolve/nr.h	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/nr.h	Sun Jan 24 15:09:55 2021 +0000
@@ -4,7 +4,7 @@
 extern bool Nr4Trace; //Spare
 extern bool NrTrace;
 
-#define NR_NAME_MAX_LENGTH     32
+#define NR_NAME_MAX_LENGTH     40
 
 extern void NrMakeRequestForNameFromAddress6(char*    address6);
 extern void NrMakeRequestForNameFromAddress4(uint32_t address4);
--- a/resolve/nrtest.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/nrtest.c	Sun Jan 24 15:09:55 2021 +0000
@@ -2,34 +2,107 @@
 #include <stdint.h>
 
 #include "nr.h"
+#include "ar6.h"
+#include "ndp.h"
 #include "dnsquery.h"
 #include "dns.h"
 #include "eth.h"
 #include "ip4addr.h"
+#include "ip6addr.h"
+#include "log.h"
+#include "mac.h"
 
 char NrTest[NR_NAME_MAX_LENGTH];
 
-static bool _doIt = false;
+static int   _ipProtocol = 0;
+static int  _dnsProtocol = 0;
+static bool _makeRequestForNameFromAddr4 = false;
+static bool _makeRequestForNameFromAddr6 = false;
+static bool _makeRequestForAddr4FromName = false;
+static bool _makeRequestForAddr6FromName = false;
+
+static uint32_t _addr4;
+static char     _addr6[16];
 
-void NrTestNameFromAddress(void)
+void NrTestSendRequest(int ipProtocol, int dnsProtocol)
 {
-    _doIt = true;
+    _ipProtocol  = ipProtocol;
+    _dnsProtocol = dnsProtocol;
+    
+    if (NrTest[0])
+    {
+        _addr4 = Ip4AddrParse(NrTest);
+        if (_addr4)
+        {
+            _makeRequestForNameFromAddr4 = true;
+        }
+        else
+        {
+            Ip6AddrParse(NrTest, _addr6);
+            if (!Ip6AddrIsEmpty(_addr6))
+            {
+                _makeRequestForNameFromAddr6 = true;
+            }
+            else
+            {
+                _makeRequestForAddr4FromName = true;
+                _makeRequestForAddr6FromName = true;
+            }
+        }
+    }
 }
-void NrTestAddress4FromName(void)
+
+static bool getMacOfDnsServer6()
 {
-    NrMakeRequestForAddress4FromName(NrTest);
-}
-void NrTestAddress6FromName(void)
-{
-    NrMakeRequestForAddress6FromName(NrTest);
+    //For IPv6 UDNS check if have the MAC for the DNS server and, if not, request it and stop
+    if (_ipProtocol == ETH_IPV6 && _dnsProtocol == DNS_PROTOCOL_UDNS)
+    {
+        char mac[6];
+        Ar6IpToMac(NdpDnsServer, mac);
+        if (MacIsEmpty(mac))
+        {
+            Ar6MakeRequestForMacFromIp(NdpDnsServer); //The request is only repeated if made after a freeze time - call as often as you want.
+            return false;
+        }
+    }
+    return true;
 }
 
 void NrTestMain(void)
 {
-    if (!_doIt) return;
     if (DnsQueryIsBusy) return;
-    uint32_t addr4 = Ip4AddrParse(NrTest);
-    if (!addr4) return;
-    DnsQueryNameFromIp4(addr4, DNS_PROTOCOL_MDNS, ETH_IPV4);
-    _doIt = false;
+    
+    
+    if (_makeRequestForNameFromAddr4)
+    {
+        //if (!getMacOfDnsServer6()) return;
+        LogTime("NrTest - making "); DnsProtocolLog(_dnsProtocol); Log(" request over "); EthProtocolLog(_ipProtocol); LogF(" for name from '%s'\r\n", NrTest);
+        DnsQueryNameFromIp4(_addr4, _dnsProtocol, _ipProtocol);
+        _makeRequestForNameFromAddr4 = false;
+        return;
+    }
+    if (_makeRequestForNameFromAddr6)
+    {
+        //if (!getMacOfDnsServer6()) return;
+        LogTime("NrTest - making "); DnsProtocolLog(_dnsProtocol); Log(" request over "); EthProtocolLog(_ipProtocol); LogF(" for name from '%s'\r\n", NrTest);
+        DnsQueryNameFromIp6(_addr6, _dnsProtocol, _ipProtocol);
+        _makeRequestForNameFromAddr6 = false;
+        return;
+    }
+    if (_makeRequestForAddr4FromName)
+    {
+        //if (!getMacOfDnsServer6()) return;
+        LogTime("NrTest - making "); DnsProtocolLog(_dnsProtocol); Log(" request over "); EthProtocolLog(_ipProtocol); LogF(" for A from '%s'\r\n", NrTest);
+        DnsQueryIp4FromName(NrTest, _dnsProtocol, _ipProtocol);
+        _makeRequestForAddr4FromName = false;
+        return;
+    }
+    if (_makeRequestForAddr6FromName)
+    {
+        //if (!getMacOfDnsServer6()) return;
+        LogTime("NrTest - making "); DnsProtocolLog(_dnsProtocol); Log(" request over "); EthProtocolLog(_ipProtocol); LogF(" for AAAA from '%s'\r\n", NrTest);
+        DnsQueryIp6FromName(NrTest, _dnsProtocol, _ipProtocol);
+        _makeRequestForAddr6FromName = false;
+        return;
+    }
 }
\ No newline at end of file
--- a/resolve/nrtest.h	Fri Jan 22 13:24:08 2021 +0000
+++ b/resolve/nrtest.h	Sun Jan 24 15:09:55 2021 +0000
@@ -1,7 +1,5 @@
 extern char NrTest[];
 
-extern void NrTestAddress4FromName(void);
-extern void NrTestAddress6FromName(void);
-extern void NrTestNameFromAddress(void);
+extern void NrTestSendRequest(int ipProtocol, int dnsProtocol);
 
 extern void NrTestMain(void);
\ No newline at end of file
--- a/udp/dns/dnsquery.c	Fri Jan 22 13:24:08 2021 +0000
+++ b/udp/dns/dnsquery.c	Sun Jan 24 15:09:55 2021 +0000
@@ -15,6 +15,9 @@
 #include  "dnshdr.h"
 #include "dnsname.h"
 #include "dnslabel.h"
+#include "ar6.h"
+#include "ndp.h"
+#include "mac.h"
 
 bool DnsQueryTrace = false;
 
@@ -159,6 +162,13 @@
     if (_RecordType  == DNS_RECORD_NONE)                       return DO_NOTHING;
     if (_DnsProtocol == DNS_PROTOCOL_NONE)                     return DO_NOTHING;
     
+    
+    //For IPv6 UDNS check if have the MAC for the DNS server and, if not, request it and stop
+    if (_IpProtocol == ETH_IPV6 && _DnsProtocol == DNS_PROTOCOL_UDNS)
+    {
+        if (!Ar6CheckHaveMacAndFetchIfNot(NdpDnsServer)) return DO_NOTHING;
+    }
+    
     NetTraceHostCheckIp6(DnsQueryIp6);
     
     if (DnsQueryTrace || NetTraceHostGetMatched()) logQuery();