A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
udp/dns/dnsquery.cpp@13:9cd54f7db57a, 2017-05-01 (annotated)
- Committer:
- andrewboyson
- Date:
- Mon May 01 18:20:55 2017 +0000
- Revision:
- 13:9cd54f7db57a
- Child:
- 14:e75a59c1123d
Added ability to read DNS queries with encoded IP addresses
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 13:9cd54f7db57a | 1 | #include "mbed.h" |
andrewboyson | 13:9cd54f7db57a | 2 | #include "log.h" |
andrewboyson | 13:9cd54f7db57a | 3 | #include "net.h" |
andrewboyson | 13:9cd54f7db57a | 4 | #include "dhcp.h" |
andrewboyson | 13:9cd54f7db57a | 5 | #include "dns.h" |
andrewboyson | 13:9cd54f7db57a | 6 | #include "udp.h" |
andrewboyson | 13:9cd54f7db57a | 7 | #include "slaac.h" |
andrewboyson | 13:9cd54f7db57a | 8 | #include "dnshdr.h" |
andrewboyson | 13:9cd54f7db57a | 9 | #include "dnsname.h" |
andrewboyson | 13:9cd54f7db57a | 10 | |
andrewboyson | 13:9cd54f7db57a | 11 | #define DEBUG true |
andrewboyson | 13:9cd54f7db57a | 12 | |
andrewboyson | 13:9cd54f7db57a | 13 | #define TIME_OUT_SENT 3 |
andrewboyson | 13:9cd54f7db57a | 14 | |
andrewboyson | 13:9cd54f7db57a | 15 | #define MDNS_UNICAST false |
andrewboyson | 13:9cd54f7db57a | 16 | |
andrewboyson | 13:9cd54f7db57a | 17 | char DnsQueryName[63]; |
andrewboyson | 13:9cd54f7db57a | 18 | uint32_t DnsQueryIp4 = 0; |
andrewboyson | 13:9cd54f7db57a | 19 | char DnsQueryIp6[16]; |
andrewboyson | 13:9cd54f7db57a | 20 | |
andrewboyson | 13:9cd54f7db57a | 21 | int DnsQueryProtocol = DNS_PROTOCOL_NONE; |
andrewboyson | 13:9cd54f7db57a | 22 | bool DnsQueryIsBusy = false; |
andrewboyson | 13:9cd54f7db57a | 23 | |
andrewboyson | 13:9cd54f7db57a | 24 | static uint32_t started = 0; |
andrewboyson | 13:9cd54f7db57a | 25 | static uint32_t elapsed = 0; |
andrewboyson | 13:9cd54f7db57a | 26 | static void reap() |
andrewboyson | 13:9cd54f7db57a | 27 | { |
andrewboyson | 13:9cd54f7db57a | 28 | if (!DnsQueryIsBusy) return; |
andrewboyson | 13:9cd54f7db57a | 29 | |
andrewboyson | 13:9cd54f7db57a | 30 | if (elapsed - started >= TIME_OUT_SENT) |
andrewboyson | 13:9cd54f7db57a | 31 | { |
andrewboyson | 13:9cd54f7db57a | 32 | char text[100]; |
andrewboyson | 13:9cd54f7db57a | 33 | LogTimeF("DNS reaped ongoing request for "); |
andrewboyson | 13:9cd54f7db57a | 34 | if (DnsQueryName[0]) LogF("name %s", DnsQueryName); |
andrewboyson | 13:9cd54f7db57a | 35 | if (DnsQueryIp4) |
andrewboyson | 13:9cd54f7db57a | 36 | { |
andrewboyson | 13:9cd54f7db57a | 37 | NetIp4AddressToString(DnsQueryIp4, sizeof(text), text); |
andrewboyson | 13:9cd54f7db57a | 38 | LogF("ip4 %s", text); |
andrewboyson | 13:9cd54f7db57a | 39 | } |
andrewboyson | 13:9cd54f7db57a | 40 | if (DnsQueryIp6[0]) |
andrewboyson | 13:9cd54f7db57a | 41 | { |
andrewboyson | 13:9cd54f7db57a | 42 | NetIp6AddressToString(DnsQueryIp6, sizeof(text), text); |
andrewboyson | 13:9cd54f7db57a | 43 | LogF("ip6 %s", text); |
andrewboyson | 13:9cd54f7db57a | 44 | } |
andrewboyson | 13:9cd54f7db57a | 45 | LogF("\r\n"); |
andrewboyson | 13:9cd54f7db57a | 46 | |
andrewboyson | 13:9cd54f7db57a | 47 | DnsQueryName[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 48 | DnsQueryIp4 = 0; |
andrewboyson | 13:9cd54f7db57a | 49 | DnsQueryIp6[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 50 | DnsQueryIsBusy = false; |
andrewboyson | 13:9cd54f7db57a | 51 | started = 0; |
andrewboyson | 13:9cd54f7db57a | 52 | DnsQueryProtocol = DNS_PROTOCOL_NONE; |
andrewboyson | 13:9cd54f7db57a | 53 | } |
andrewboyson | 13:9cd54f7db57a | 54 | } |
andrewboyson | 13:9cd54f7db57a | 55 | void DnsQueryTick() |
andrewboyson | 13:9cd54f7db57a | 56 | { |
andrewboyson | 13:9cd54f7db57a | 57 | elapsed++; |
andrewboyson | 13:9cd54f7db57a | 58 | reap(); |
andrewboyson | 13:9cd54f7db57a | 59 | } |
andrewboyson | 13:9cd54f7db57a | 60 | void DnsQueryIp4FromName(char * name, int protocol) |
andrewboyson | 13:9cd54f7db57a | 61 | { |
andrewboyson | 13:9cd54f7db57a | 62 | strcpy(DnsQueryName, name); |
andrewboyson | 13:9cd54f7db57a | 63 | DnsQueryIp4 = 0; |
andrewboyson | 13:9cd54f7db57a | 64 | DnsQueryIp6[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 65 | DnsQueryIsBusy = true; |
andrewboyson | 13:9cd54f7db57a | 66 | started = elapsed; |
andrewboyson | 13:9cd54f7db57a | 67 | DnsQueryProtocol = protocol; |
andrewboyson | 13:9cd54f7db57a | 68 | } |
andrewboyson | 13:9cd54f7db57a | 69 | void DnsQueryIp6FromName(char * name, int protocol) |
andrewboyson | 13:9cd54f7db57a | 70 | { |
andrewboyson | 13:9cd54f7db57a | 71 | strcpy(DnsQueryName, name); |
andrewboyson | 13:9cd54f7db57a | 72 | DnsQueryIp4 = 0; |
andrewboyson | 13:9cd54f7db57a | 73 | DnsQueryIp6[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 74 | DnsQueryIsBusy = true; |
andrewboyson | 13:9cd54f7db57a | 75 | started = elapsed; |
andrewboyson | 13:9cd54f7db57a | 76 | DnsQueryProtocol = protocol; |
andrewboyson | 13:9cd54f7db57a | 77 | } |
andrewboyson | 13:9cd54f7db57a | 78 | void DnsQueryNameFromIp4(uint32_t ip, int protocol) |
andrewboyson | 13:9cd54f7db57a | 79 | { |
andrewboyson | 13:9cd54f7db57a | 80 | DnsQueryName[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 81 | DnsQueryIp4 = ip; |
andrewboyson | 13:9cd54f7db57a | 82 | DnsQueryIp6[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 83 | DnsQueryIsBusy = true; |
andrewboyson | 13:9cd54f7db57a | 84 | started = elapsed; |
andrewboyson | 13:9cd54f7db57a | 85 | DnsQueryProtocol = protocol; |
andrewboyson | 13:9cd54f7db57a | 86 | } |
andrewboyson | 13:9cd54f7db57a | 87 | void DnsQueryNameFromIp6(char* ip, int protocol) |
andrewboyson | 13:9cd54f7db57a | 88 | { |
andrewboyson | 13:9cd54f7db57a | 89 | DnsQueryName[0] = 0; |
andrewboyson | 13:9cd54f7db57a | 90 | DnsQueryIp4 = 0; |
andrewboyson | 13:9cd54f7db57a | 91 | memcpy(DnsQueryIp6, ip, 16); |
andrewboyson | 13:9cd54f7db57a | 92 | DnsQueryIsBusy = true; |
andrewboyson | 13:9cd54f7db57a | 93 | started = elapsed; |
andrewboyson | 13:9cd54f7db57a | 94 | DnsQueryProtocol = protocol; |
andrewboyson | 13:9cd54f7db57a | 95 | } |
andrewboyson | 13:9cd54f7db57a | 96 | int DnsQueryPoll(int* pSize) |
andrewboyson | 13:9cd54f7db57a | 97 | { |
andrewboyson | 13:9cd54f7db57a | 98 | if (!DnsQueryIsBusy) return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 99 | if (DnsQueryProtocol == DNS_PROTOCOL_UDNS && DhcpLocalIp == 0) return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 100 | |
andrewboyson | 13:9cd54f7db57a | 101 | static uint16_t id = 0; |
andrewboyson | 13:9cd54f7db57a | 102 | DnsHdrId = ++id; |
andrewboyson | 13:9cd54f7db57a | 103 | DnsHdrIsReply = false; |
andrewboyson | 13:9cd54f7db57a | 104 | DnsHdrIsRecursiveQuery = false; |
andrewboyson | 13:9cd54f7db57a | 105 | |
andrewboyson | 13:9cd54f7db57a | 106 | DnsHdrQdcount = 1; |
andrewboyson | 13:9cd54f7db57a | 107 | DnsHdrAncount = 0; |
andrewboyson | 13:9cd54f7db57a | 108 | DnsHdrNscount = 0; |
andrewboyson | 13:9cd54f7db57a | 109 | DnsHdrArcount = 0; |
andrewboyson | 13:9cd54f7db57a | 110 | |
andrewboyson | 13:9cd54f7db57a | 111 | DnsHdrWrite(); |
andrewboyson | 13:9cd54f7db57a | 112 | char* p = DnsHdrData; |
andrewboyson | 13:9cd54f7db57a | 113 | |
andrewboyson | 13:9cd54f7db57a | 114 | if (DnsQueryIp4) //Reverse |
andrewboyson | 13:9cd54f7db57a | 115 | { |
andrewboyson | 13:9cd54f7db57a | 116 | if (DEBUG) |
andrewboyson | 13:9cd54f7db57a | 117 | { |
andrewboyson | 13:9cd54f7db57a | 118 | char text[20]; |
andrewboyson | 13:9cd54f7db57a | 119 | NetIp4AddressToString(DnsQueryIp4, sizeof(text), text); |
andrewboyson | 13:9cd54f7db57a | 120 | switch (DnsQueryProtocol) |
andrewboyson | 13:9cd54f7db57a | 121 | { |
andrewboyson | 13:9cd54f7db57a | 122 | case DNS_PROTOCOL_UDNS: LogTimeF("DNS sent DNS reverse request for %s\r\n", text); break; |
andrewboyson | 13:9cd54f7db57a | 123 | case DNS_PROTOCOL_MDNS: LogTimeF("DNS sent MDNS reverse request for %s\r\n", text); break; |
andrewboyson | 13:9cd54f7db57a | 124 | case DNS_PROTOCOL_LLMNR: LogTimeF("DNS sent LLMNR reverse request for %s\r\n", text); break; |
andrewboyson | 13:9cd54f7db57a | 125 | } |
andrewboyson | 13:9cd54f7db57a | 126 | } |
andrewboyson | 13:9cd54f7db57a | 127 | DnsNameEncodeIp4(DnsQueryIp4, &p); |
andrewboyson | 13:9cd54f7db57a | 128 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 129 | *p++ = DNS_RECORD_PTR; |
andrewboyson | 13:9cd54f7db57a | 130 | } |
andrewboyson | 13:9cd54f7db57a | 131 | else if (DnsQueryIp6[0]) |
andrewboyson | 13:9cd54f7db57a | 132 | { |
andrewboyson | 13:9cd54f7db57a | 133 | if (DEBUG) |
andrewboyson | 13:9cd54f7db57a | 134 | { |
andrewboyson | 13:9cd54f7db57a | 135 | char text[60]; |
andrewboyson | 13:9cd54f7db57a | 136 | NetIp6AddressToString(DnsQueryIp6, sizeof(text), text); |
andrewboyson | 13:9cd54f7db57a | 137 | switch (DnsQueryProtocol) |
andrewboyson | 13:9cd54f7db57a | 138 | { |
andrewboyson | 13:9cd54f7db57a | 139 | case DNS_PROTOCOL_UDNS: LogTimeF("DNS sent DNS reverse request for %s\r\n", text); break; |
andrewboyson | 13:9cd54f7db57a | 140 | case DNS_PROTOCOL_MDNS: LogTimeF("DNS sent MDNS reverse request for %s\r\n", text); break; |
andrewboyson | 13:9cd54f7db57a | 141 | case DNS_PROTOCOL_LLMNR: LogTimeF("DNS sent LLMNR reverse request for %s\r\n", text); break; |
andrewboyson | 13:9cd54f7db57a | 142 | } |
andrewboyson | 13:9cd54f7db57a | 143 | } |
andrewboyson | 13:9cd54f7db57a | 144 | DnsNameEncodeIp6(DnsQueryIp6, &p); |
andrewboyson | 13:9cd54f7db57a | 145 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 146 | *p++ = DNS_RECORD_PTR; |
andrewboyson | 13:9cd54f7db57a | 147 | } |
andrewboyson | 13:9cd54f7db57a | 148 | else //Forward |
andrewboyson | 13:9cd54f7db57a | 149 | { |
andrewboyson | 13:9cd54f7db57a | 150 | DnsNameEncode(DnsQueryName, &p); |
andrewboyson | 13:9cd54f7db57a | 151 | *p++ = 0; |
andrewboyson | 13:9cd54f7db57a | 152 | *p++ = DNS_RECORD_A; |
andrewboyson | 13:9cd54f7db57a | 153 | } |
andrewboyson | 13:9cd54f7db57a | 154 | *p++ = DnsQueryProtocol == DNS_PROTOCOL_MDNS && MDNS_UNICAST ? 0x80 : 0; //Set the 15th bit (UNICAST_RESPONSE) to 1 if MDNS |
andrewboyson | 13:9cd54f7db57a | 155 | *p++ = 1; //QCLASS_IN = 1 - internet |
andrewboyson | 13:9cd54f7db57a | 156 | |
andrewboyson | 13:9cd54f7db57a | 157 | *pSize = p - DnsHdrPacket; |
andrewboyson | 13:9cd54f7db57a | 158 | |
andrewboyson | 13:9cd54f7db57a | 159 | DnsQueryIsBusy = false; |
andrewboyson | 13:9cd54f7db57a | 160 | |
andrewboyson | 13:9cd54f7db57a | 161 | switch (DnsQueryProtocol) |
andrewboyson | 13:9cd54f7db57a | 162 | { |
andrewboyson | 13:9cd54f7db57a | 163 | case DNS_PROTOCOL_UDNS: return UNICAST_DNS; //IPv6 ==> NdpDnsServer; IPv4 ==> DhcpDnsServer |
andrewboyson | 13:9cd54f7db57a | 164 | case DNS_PROTOCOL_MDNS: return MULTICAST_MDNS; |
andrewboyson | 13:9cd54f7db57a | 165 | case DNS_PROTOCOL_LLMNR: return MULTICAST_LLMNR; |
andrewboyson | 13:9cd54f7db57a | 166 | default: |
andrewboyson | 13:9cd54f7db57a | 167 | LogTimeF("DNS unknown query protocol %d\r\n", DnsQueryProtocol); |
andrewboyson | 13:9cd54f7db57a | 168 | return DO_NOTHING; |
andrewboyson | 13:9cd54f7db57a | 169 | } |
andrewboyson | 13:9cd54f7db57a | 170 | } |