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
dnshdr.c
00001 #include <stdint.h> 00002 #include <stdbool.h> 00003 00004 #include "dns.h" 00005 #include "net.h" 00006 #include "log.h" 00007 #include "net.h" 00008 #include "eth.h" 00009 #include "ip4addr.h" 00010 #include "ip6addr.h" 00011 #include "udp.h" 00012 #include "dnsname.h" 00013 #include "dnslabel.h" 00014 00015 #define HEADER_LENGTH 12 00016 00017 uint16_t DnsHdrId; 00018 00019 bool DnsHdrIsReply; 00020 bool DnsHdrIsAuthoritative; 00021 bool DnsHdrIsRecursiveQuery; 00022 00023 uint16_t DnsHdrQdcount; 00024 uint16_t DnsHdrAncount; 00025 uint16_t DnsHdrNscount; 00026 uint16_t DnsHdrArcount; 00027 00028 char* DnsHdrPacket; 00029 char* DnsHdrData; 00030 int DnsHdrDataLength; 00031 00032 void DnsHdrSetup(void* pPacket, int lenPacket) 00033 { 00034 DnsHdrPacket = (char*)pPacket; 00035 DnsHdrData = DnsHdrPacket + HEADER_LENGTH; 00036 DnsHdrDataLength = lenPacket - HEADER_LENGTH; 00037 } 00038 00039 void DnsHdrRead() 00040 { 00041 NetInvert16(&DnsHdrId, DnsHdrPacket + 0); 00042 00043 uint8_t uflags = *(DnsHdrPacket + 2); 00044 DnsHdrIsReply = uflags & 0x80; 00045 DnsHdrIsAuthoritative = uflags & 0x04; 00046 DnsHdrIsRecursiveQuery = uflags & 0x01; 00047 00048 NetInvert16(&DnsHdrQdcount, DnsHdrPacket + 4); 00049 NetInvert16(&DnsHdrAncount, DnsHdrPacket + 6); 00050 NetInvert16(&DnsHdrNscount, DnsHdrPacket + 8); 00051 NetInvert16(&DnsHdrArcount, DnsHdrPacket + 10); 00052 } 00053 void DnsHdrWrite() 00054 { 00055 NetInvert16(DnsHdrPacket + 0, &DnsHdrId); 00056 00057 uint8_t uflags = 0; 00058 uint8_t lflags = 0; 00059 if (DnsHdrIsReply) uflags |= 0x80; 00060 if (DnsHdrIsAuthoritative) uflags |= 0x04; 00061 if (DnsHdrIsRecursiveQuery) uflags |= 0x01; 00062 *(DnsHdrPacket + 2) = uflags; 00063 *(DnsHdrPacket + 3) = lflags; 00064 00065 NetInvert16(DnsHdrPacket + 4, &DnsHdrQdcount); 00066 NetInvert16(DnsHdrPacket + 6, &DnsHdrAncount); 00067 NetInvert16(DnsHdrPacket + 8, &DnsHdrNscount); 00068 NetInvert16(DnsHdrPacket + 10, &DnsHdrArcount); 00069 00070 } 00071 static uint16_t decodeUint16(char* p) 00072 { 00073 uint16_t value = *p++; 00074 value <<= 8; value += *p++; 00075 return value; 00076 } 00077 static uint32_t decodeUint32(char* p) 00078 { 00079 uint32_t value = *p++; 00080 value <<= 8; value += *p++; 00081 value <<= 8; value += *p++; 00082 value <<= 8; value += *p++; 00083 return value; 00084 } 00085 static void logRecordA(int len, char* p) 00086 { 00087 if (len == 4) Ip4AddrLog(*(uint32_t*)p); 00088 else LogF("expected 4 bytes but had %d", len); 00089 } 00090 static void logRecordAAAA(int len, char* p) 00091 { 00092 if (len == 16) Ip6AddrLog(p); 00093 else LogF("expected 16 bytes but had %d", len); 00094 } 00095 static void logRecordPTR(int len, char* p) 00096 { 00097 if (len <= DNS_MAX_LABEL_LENGTH) DnsNameLogPtr(p); 00098 else LogF("length %d is greater than max DNS label length of %d\r\n", len, DNS_MAX_LABEL_LENGTH); 00099 } 00100 static void logRecordSRV(int len, char* p) 00101 { 00102 LogF("pri=%d " , decodeUint16(p)); p += 2; 00103 LogF("wei=%d " , decodeUint16(p)); p += 2; 00104 LogF("port=%d ", decodeUint16(p)); p += 2; 00105 DnsNameLogPtr(p); 00106 } 00107 static void logRecordTXT(int len, char* p) 00108 { 00109 char* pEnd = p + len; 00110 while (p < pEnd) 00111 { 00112 Log("\r\n "); 00113 int fieldLen = *p++; 00114 for (int i = 0; i < fieldLen; i++) LogChar(*p++); 00115 } 00116 } 00117 static void logContent() 00118 { 00119 char* p = DnsHdrData; 00120 00121 //Get the questions 00122 for (int q = 0; q < DnsHdrQdcount; q++) 00123 { 00124 if (p >= DnsHdrData + DnsHdrDataLength) 00125 { 00126 Log(" Questions have overrun the buffer\r\n"); 00127 return; 00128 } 00129 char* pEncodedName = p; 00130 int nameLength = DnsNameLength(p); 00131 if (!nameLength) { LogTimeF(" Questions namelength is zero\r\n"); return; } 00132 p += nameLength; //Skip past the name 00133 p++ ; //skip the first byte of the type 00134 char recordType = *p++; //read the record type 00135 p += 2; //skip the class 00136 00137 LogF(" Query "); 00138 DnsRecordTypeLog(recordType); 00139 Log(" type record of "); 00140 DnsNameLogPtr(pEncodedName); 00141 Log("\r\n"); 00142 } 00143 00144 //Get the answers 00145 for (int a = 0; a < DnsHdrAncount; a++) 00146 { 00147 if (p >= DnsHdrData + DnsHdrDataLength) { Log(" Answers have overrun the buffer\r\n"); return; } 00148 00149 char* pEncodedName = p; 00150 int nameLength = DnsNameLength(p); 00151 if (!nameLength) { Log(" Answer name length is zero\r\n"); return; } 00152 p += nameLength; //Skip past the name 00153 00154 p++; //Skip the high byte of the record type 00155 int recordType = *p++; //Record type 00156 00157 p++; //Skip the high byte of the class type 00158 int classType = *p++; //Class type 00159 00160 int ttl = decodeUint32(p); p += 4; //32bit TTL 00161 00162 int len = decodeUint16(p); p += 2; //16bit length 00163 00164 Log(" Answer "); 00165 DnsRecordTypeLog(recordType); 00166 Log(" type record of "); 00167 DnsNameLogPtr(pEncodedName); 00168 Log(" ==> "); 00169 00170 switch (recordType) //Log the payload if its type is known 00171 { 00172 case DNS_RECORD_A: logRecordA (len, p); break; 00173 case DNS_RECORD_AAAA: logRecordAAAA(len, p); break; 00174 case DNS_RECORD_PTR: logRecordPTR (len, p); break; 00175 case DNS_RECORD_SRV: logRecordSRV (len, p); break; 00176 case DNS_RECORD_TXT: logRecordTXT (len, p); break; 00177 default: LogF("%d characters", len); break; 00178 } 00179 Log("\r\n"); 00180 p += len; //Adjust the pointer to the next character after the payload 00181 } 00182 } 00183 00184 void DnsHdrLog(int protocol) 00185 { 00186 if (NetTraceVerbose) 00187 { 00188 DnsProtocolLog(protocol); 00189 Log(" header\r\n"); 00190 LogF(" Ident %hd\r\n", DnsHdrId); 00191 if (DnsHdrIsReply) 00192 { 00193 if (DnsHdrIsAuthoritative) LogF(" Authoritative reply\r\n"); 00194 else LogF(" Non authoritative reply\r\n"); 00195 } 00196 else 00197 { 00198 if (DnsHdrIsRecursiveQuery) LogF(" Recursive query\r\n"); 00199 else LogF(" Non recursive query\r\n"); 00200 } 00201 LogF(" qd, an, ns, ar %hu, %hu, %hu, %hu\r\n", DnsHdrQdcount, DnsHdrAncount, DnsHdrNscount, DnsHdrArcount); 00202 } 00203 else 00204 { 00205 DnsProtocolLog(protocol); 00206 LogF(" header qd, an, ns, ar %hu, %hu, %hu, %hu\r\n", DnsHdrQdcount, DnsHdrAncount, DnsHdrNscount, DnsHdrArcount); 00207 } 00208 logContent(); 00209 } 00210
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2