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/dnsreply.cpp
- Committer:
- andrewboyson
- Date:
- 2017-08-10
- Revision:
- 30:e34173b7585c
- Parent:
- 22:914b970356f0
- Child:
- 32:679654f2d023
File content as of revision 30:e34173b7585c:
#include "mbed.h" #include "log.h" #include "net.h" #include "ip4.h" #include "ip6.h" #include "ar.h" #include "dnscache.h" #include "dns.h" #include "dnshdr.h" #include "dnsname.h" #define DEBUG false char DnsReplyRecordName[256]; uint32_t DnsReplyRecordNameAsIp4 = 0; char DnsReplyRecordNameAsIp6[16]; char DnsReplyName[64]; uint32_t DnsReplyIp4 = 0; char DnsReplyIp6[16]; static char *p; static int recordNameOffset; static int recordType; static int recordDataLength; static char* pRecordData; static int scanQuery() { int recordNameLength = DnsNameLength(p); if (!recordNameLength) { if (DEBUG) LogTimeF("DnsReply scanRecord name length of zero\r\n"); return -1; //failure } recordNameOffset = DnsNameIndexFromPointer(p); p += recordNameLength; p++ ; //skip the first byte of the type recordType = *p++; p += 2; //skip the class return 0; //success } static int scanAnswer() { int recordNameLength = DnsNameLength(p); if (!recordNameLength) { if (DEBUG) LogTimeF("DnsReply scanRecord name length of zero\r\n"); return -1; //failure } recordNameOffset = DnsNameIndexFromPointer(p); p += recordNameLength; p++ ; //skip the first byte of the type recordType = *p++; p += 6; //skip the class, TTL recordDataLength = 0; recordDataLength |= *p++ << 8; recordDataLength |= *p++; pRecordData = p; //record the start of the data p += recordDataLength; //Move to the start of the next record return 0; //success } static void readAnswer() { DnsReplyRecordName[0] = 0; DnsReplyRecordNameAsIp4 = 0; DnsReplyRecordNameAsIp6[0] = 0; DnsReplyName[0] = 0; DnsReplyIp4 = 0; DnsReplyIp6[0] = 0; switch (recordType) { case DNS_RECORD_A: case DNS_RECORD_AAAA: case DNS_RECORD_PTR: case DNS_RECORD_SRV: case DNS_RECORD_TXT: break; default: LogTimeF("DnsReply readAnswer unrecognised record type %d\r\n", recordType); return; } DnsNameDecode (recordNameOffset, sizeof(DnsReplyRecordName), DnsReplyRecordName); DnsNameDecodeIp4(recordNameOffset, &DnsReplyRecordNameAsIp4); DnsNameDecodeIp6(recordNameOffset, DnsReplyRecordNameAsIp6); switch (recordType) { case DNS_RECORD_A: if (recordDataLength != 4) { LogTimeF("DnsReply A type length of %d\r\n", recordDataLength); return; } memcpy(&DnsReplyIp4, pRecordData, 4); break; case DNS_RECORD_AAAA: if (recordDataLength != 16) { LogTimeF("DnsReply AAAA type length of %d\r\n", recordDataLength); return; } memcpy(DnsReplyIp6, pRecordData, 16); break; case DNS_RECORD_PTR: if (recordDataLength > 63) { LogTimeF("DnsReply PTR type length of %d\r\n", recordDataLength); return; } DnsNameDecode(DnsNameIndexFromPointer(pRecordData), sizeof(DnsReplyName), DnsReplyName); break; } if (DEBUG) { LogF(" answer: %s", DnsReplyRecordName); char text[100]; if (DnsReplyRecordNameAsIp4) { Ip4AddressToString(DnsReplyRecordNameAsIp4, sizeof(text), text); LogF(" (%s)", text); } if (DnsReplyRecordNameAsIp6[0]) { Ip6AddressToString(DnsReplyRecordNameAsIp6, sizeof(text), text); LogF(" (%s)", text); } LogF(" == "); switch (recordType) { case DNS_RECORD_A: Ip4AddressToString(DnsReplyIp4, sizeof(text), text); LogF("%s\r\n", text); break; case DNS_RECORD_AAAA: Ip6AddressToString(DnsReplyIp6, sizeof(text), text); LogF("%s\r\n", text); break; case DNS_RECORD_PTR: LogF("%s\r\n", DnsReplyName); break; default: DnsRecordTypeToString(recordType, sizeof(text), text); LogF("%d bytes of %s\r\n", recordDataLength, text); break; } } } static void sendToAr(int dnsProtocol) { if (DnsReplyIp4 && DnsReplyRecordName[0]) ArAddName4(DnsReplyIp4, DnsReplyRecordName, dnsProtocol); if (DnsReplyIp6[0] && DnsReplyRecordName[0]) ArAddName6(DnsReplyIp6, DnsReplyRecordName, dnsProtocol); if (DnsReplyRecordNameAsIp4 && DnsReplyName[0] ) ArAddName4(DnsReplyRecordNameAsIp4, DnsReplyName, dnsProtocol); if (DnsReplyRecordNameAsIp6[0] && DnsReplyName[0] ) ArAddName6(DnsReplyRecordNameAsIp6, DnsReplyName, dnsProtocol); } static void sendToDn(int dnsProtocol) { if (DnsReplyIp4 && DnsReplyRecordName[0]) DnsCacheAddIp4Record(DnsReplyIp4, DnsReplyRecordName, dnsProtocol); if (DnsReplyIp6[0] && DnsReplyRecordName[0]) DnsCacheAddIp6Record(DnsReplyIp6, DnsReplyRecordName, dnsProtocol); if (DnsReplyRecordNameAsIp4 && DnsReplyName[0] ) DnsCacheAddIp4Record(DnsReplyRecordNameAsIp4, DnsReplyName, dnsProtocol); if (DnsReplyRecordNameAsIp6[0] && DnsReplyName[0] ) DnsCacheAddIp6Record(DnsReplyRecordNameAsIp6, DnsReplyName, dnsProtocol); } int DnsReplyHandle(int dnsProtocol, int *pSize) { if (!DnsHdrAncount) return DO_NOTHING; if (DEBUG) DnsHdrLog("received reply", dnsProtocol); p = DnsHdrData; for (int q = 0; q < DnsHdrQdcount; q++) { if (scanQuery()) return DO_NOTHING; } for (int a = 0; a < DnsHdrAncount; a++) { if (scanAnswer()) return DO_NOTHING; readAnswer(); sendToAr(dnsProtocol); sendToDn(dnsProtocol); } return DO_NOTHING; }