MeterLogger
Macros | Functions | Variables
captdns.c File Reference
#include <esp8266.h>
#include <lwip/ip.h>
#include <lwip/udp.h>
#include <lwip/tcp_impl.h>
#include <netif/etharp.h>
#include <lwip/netif.h>
#include <lwip/lwip_napt.h>
#include <lwip/dns.h>
#include <lwip/app/dhcpserver.h>
#include <lwip/opt.h>
#include <espconn.h>
Include dependency graph for captdns.c:

Go to the source code of this file.

Macros

#define DNS_LEN   512
 
#define FLAG_QR   (1<<7)
 
#define FLAG_AA   (1<<2)
 
#define FLAG_TC   (1<<1)
 
#define FLAG_RD   (1<<0)
 
#define QTYPE_A   1
 
#define QTYPE_NS   2
 
#define QTYPE_CNAME   5
 
#define QTYPE_SOA   6
 
#define QTYPE_WKS   11
 
#define QTYPE_PTR   12
 
#define QTYPE_HINFO   13
 
#define QTYPE_MINFO   14
 
#define QTYPE_MX   15
 
#define QTYPE_TXT   16
 
#define QTYPE_URI   256
 
#define QCLASS_IN   1
 
#define QCLASS_ANY   255
 
#define QCLASS_URI   256
 

Functions

struct __attribute__ ((packed))
 
static void ICACHE_FLASH_ATTR setn16 (void *pp, int16_t n)
 
static void ICACHE_FLASH_ATTR setn32 (void *pp, int32_t n)
 
static uint16_t ICACHE_FLASH_ATTR my_ntohs (uint16_t *in)
 
static char *ICACHE_FLASH_ATTR labelToStr (char *packet, char *labelPtr, int packetSz, char *res, int resMaxLen)
 
static char ICACHE_FLASH_ATTRstrToLabel (char *str, char *label, int maxLen)
 
static void ICACHE_FLASH_ATTR captdnsRecv (void *arg, char *pusrdata, unsigned short length)
 
void ICACHE_FLASH_ATTR captdnsInit (void)
 
void ICACHE_FLASH_ATTR captdnsStop (void)
 

Variables

static struct espconn conn
 
 DnsHeader
 
 DnsLabel
 
 DnsQuestionFooter
 
 DnsResourceFooter
 
 DnsUriHdr
 

Macro Definition Documentation

◆ DNS_LEN

#define DNS_LEN   512

Definition at line 47 of file captdns.c.

Referenced by captdnsRecv().

◆ FLAG_AA

#define FLAG_AA   (1<<2)

Definition at line 93 of file captdns.c.

◆ FLAG_QR

#define FLAG_QR   (1<<7)

Definition at line 92 of file captdns.c.

Referenced by captdnsRecv().

◆ FLAG_RD

#define FLAG_RD   (1<<0)

Definition at line 95 of file captdns.c.

◆ FLAG_TC

#define FLAG_TC   (1<<1)

Definition at line 94 of file captdns.c.

Referenced by captdnsRecv().

◆ QCLASS_ANY

#define QCLASS_ANY   255

Definition at line 110 of file captdns.c.

◆ QCLASS_IN

#define QCLASS_IN   1

Definition at line 109 of file captdns.c.

Referenced by captdnsRecv().

◆ QCLASS_URI

#define QCLASS_URI   256

Definition at line 111 of file captdns.c.

Referenced by captdnsRecv().

◆ QTYPE_A

#define QTYPE_A   1

Definition at line 97 of file captdns.c.

Referenced by captdnsRecv().

◆ QTYPE_CNAME

#define QTYPE_CNAME   5

Definition at line 99 of file captdns.c.

◆ QTYPE_HINFO

#define QTYPE_HINFO   13

Definition at line 103 of file captdns.c.

◆ QTYPE_MINFO

#define QTYPE_MINFO   14

Definition at line 104 of file captdns.c.

◆ QTYPE_MX

#define QTYPE_MX   15

Definition at line 105 of file captdns.c.

◆ QTYPE_NS

#define QTYPE_NS   2

Definition at line 98 of file captdns.c.

Referenced by captdnsRecv().

◆ QTYPE_PTR

#define QTYPE_PTR   12

Definition at line 102 of file captdns.c.

◆ QTYPE_SOA

#define QTYPE_SOA   6

Definition at line 100 of file captdns.c.

◆ QTYPE_TXT

#define QTYPE_TXT   16

Definition at line 106 of file captdns.c.

◆ QTYPE_URI

#define QTYPE_URI   256

Definition at line 107 of file captdns.c.

Referenced by captdnsRecv().

◆ QTYPE_WKS

#define QTYPE_WKS   11

Definition at line 101 of file captdns.c.

Function Documentation

◆ __attribute__()

struct __attribute__ ( (packed)  )

Definition at line 53 of file captdns.c.

Referenced by espconn_sendto().

53  {
54  uint16_t id;
55  uint8_t flags;
56  uint8_t rcode;
57  uint16_t qdcount;
58  uint16_t ancount;
59  uint16_t nscount;
60  uint16_t arcount;
61 } DnsHeader;
DnsHeader
Definition: captdns.c:61
Here is the caller graph for this function:

◆ captdnsInit()

void ICACHE_FLASH_ATTR captdnsInit ( void  )

Definition at line 344 of file captdns.c.

References captdnsRecv(), espconn_create(), espconn_regist_recvcb(), ESPCONN_UDP, _esp_udp::local_port, espconn::proto, espconn::type, and espconn::udp.

Referenced by captdnsRecv().

344  {
345  static esp_udp udpconn;
347  conn.proto.udp=&udpconn;
348  conn.proto.udp->local_port = 53;
351 }
esp_udp * udp
Definition: espconn.h:106
sint8 espconn_regist_recvcb(struct espconn *espconn, espconn_recv_callback recv_cb)
Definition: espconn.c:770
int local_port
Definition: espconn.h:83
static struct espconn conn
Definition: captdns.c:50
union espconn::@1 proto
enum espconn_type type
Definition: espconn.h:101
static void ICACHE_FLASH_ATTR captdnsRecv(void *arg, char *pusrdata, unsigned short length)
Definition: captdns.c:192
sint8 espconn_create(struct espconn *espconn)
Definition: espconn.c:334
Here is the call graph for this function:
Here is the caller graph for this function:

◆ captdnsRecv()

static void ICACHE_FLASH_ATTR captdnsRecv ( void *  arg,
char *  pusrdata,
unsigned short  length 
)
static

Definition at line 192 of file captdns.c.

References captdnsInit(), conn, DNS_LEN, DnsHeader, DnsQuestionFooter, DnsResourceFooter, DnsUriHdr, espconn_get_connection_info(), ESPCONN_OK, espconn_sendto(), FLAG_QR, FLAG_TC, htons, ICACHE_FLASH_ATTR, INADDR_ANY, ip_info::ip, ip4_addr1, ip4_addr2, ip4_addr3, ip4_addr4, labelToStr(), memcpy, memset, my_ntohs(), NULL, espconn::proto, QCLASS_IN, QCLASS_URI, QTYPE_A, QTYPE_NS, QTYPE_URI, _esp_udp::remote_ip, _remot_info::remote_ip, _esp_udp::remote_port, _remot_info::remote_port, setn16(), setn32(), SOFTAP_IF, strToLabel(), espconn::udp, and wifi_get_ip_info().

Referenced by captdnsInit().

192  {
193  struct espconn *conn=(struct espconn *)arg;
194 #else
195 static void ICACHE_FLASH_ATTR captdnsRecv(struct sockaddr_in *premote_addr, char *pusrdata, unsigned short length) {
196 #endif
197  char buff[DNS_LEN];
198  char reply[DNS_LEN];
199  int i;
200  char *rend=&reply[length];
201  char *p=pusrdata;
202  DnsHeader *hdr=(DnsHeader*)p;
203  DnsHeader *rhdr=(DnsHeader*)&reply[0];
204  p+=sizeof(DnsHeader);
205 // httpd_printf("DNS packet: id 0x%X flags 0x%X rcode 0x%X qcnt %d ancnt %d nscount %d arcount %d len %d\n",
206 // my_ntohs(&hdr->id), hdr->flags, hdr->rcode, my_ntohs(&hdr->qdcount), my_ntohs(&hdr->ancount), my_ntohs(&hdr->nscount), my_ntohs(&hdr->arcount), length);
207  //Some sanity checks:
208  if (length>DNS_LEN) return; //Packet is longer than DNS implementation allows
209  if (length<sizeof(DnsHeader)) return; //Packet is too short
210  if (hdr->ancount || hdr->nscount || hdr->arcount) return; //this is a reply, don't know what to do with it
211  if (hdr->flags&FLAG_TC) return; //truncated, can't use this
212  //Reply is basically the request plus the needed data
213  memcpy(reply, pusrdata, length);
214  rhdr->flags|=FLAG_QR;
215  for (i=0; i<my_ntohs(&hdr->qdcount); i++) {
216  //Grab the labels in the q string
217  p=labelToStr(pusrdata, p, length, buff, sizeof(buff));
218  if (p==NULL) return;
220  p+=sizeof(DnsQuestionFooter);
221 // httpd_printf("DNS: Q (type 0x%X class 0x%X) for %s\n", my_ntohs(&qf->type), my_ntohs(&qf->class), buff);
222  if (my_ntohs(&qf->type)==QTYPE_A) {
223  //They want to know the IPv4 address of something.
224  //Build the response.
225  rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label
226  if (rend==NULL) return;
228  rend+=sizeof(DnsResourceFooter);
229  setn16(&rf->type, QTYPE_A);
230  setn16(&rf->class, QCLASS_IN);
231  setn32(&rf->ttl, 0);
232  setn16(&rf->rdlength, 4); //IPv4 addr is 4 bytes;
233  //Grab the current IP of the softap interface
234  struct ip_info info;
235  wifi_get_ip_info(SOFTAP_IF, &info);
236  *rend++=ip4_addr1(&info.ip);
237  *rend++=ip4_addr2(&info.ip);
238  *rend++=ip4_addr3(&info.ip);
239  *rend++=ip4_addr4(&info.ip);
240  setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1);
241 // httpd_printf("Added A rec to resp. Resp len is %d\n", (rend-reply));
242  } else if (my_ntohs(&qf->type)==QTYPE_NS) {
243  //Give ns server. Basically can be whatever we want because it'll get resolved to our IP later anyway.
244  rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label
246  rend+=sizeof(DnsResourceFooter);
247  setn16(&rf->type, QTYPE_NS);
248  setn16(&rf->class, QCLASS_IN);
249  setn16(&rf->ttl, 0);
250  setn16(&rf->rdlength, 4);
251  *rend++=2;
252  *rend++='n';
253  *rend++='s';
254  *rend++=0;
255  setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1);
256 // httpd_printf("Added NS rec to resp. Resp len is %d\n", (rend-reply));
257  } else if (my_ntohs(&qf->type)==QTYPE_URI) {
258  //Give uri to us
259  rend=strToLabel(buff, rend, sizeof(reply)-(rend-reply)); //Add the label
261  rend+=sizeof(DnsResourceFooter);
262  DnsUriHdr *uh=(DnsUriHdr *)rend;
263  rend+=sizeof(DnsUriHdr);
264  setn16(&rf->type, QTYPE_URI);
265  setn16(&rf->class, QCLASS_URI);
266  setn16(&rf->ttl, 0);
267  setn16(&rf->rdlength, 4+16);
268  setn16(&uh->prio, 10);
269  setn16(&uh->weight, 1);
270  memcpy(rend, "http://esp.nonet", 16);
271  rend+=16;
272  setn16(&rhdr->ancount, my_ntohs(&rhdr->ancount)+1);
273 // httpd_printf("Added NS rec to resp. Resp len is %d\n", (rend-reply));
274  }
275  }
276  //Send the response
277 #ifndef FREERTOS
278  remot_info *remInfo=NULL;
279  //Send data to port/ip it came from, not to the ip/port we listen on.
280  if (espconn_get_connection_info(conn, &remInfo, 0)==ESPCONN_OK) {
281  conn->proto.udp->remote_port=remInfo->remote_port;
282  memcpy(conn->proto.udp->remote_ip, remInfo->remote_ip, sizeof(remInfo->remote_ip));
283  }
284  espconn_sendto(conn, (uint8*)reply, rend-reply);
285 #else
286  sendto(sockFd,(uint8*)reply, rend-reply, 0, (struct sockaddr *)premote_addr, sizeof(struct sockaddr_in));
287 #endif
288 }
esp_udp * udp
Definition: espconn.h:106
#define SOFTAP_IF
static void ICACHE_FLASH_ATTR setn32(void *pp, int32_t n)
Definition: captdns.c:122
DnsHeader
Definition: captdns.c:61
static struct espconn conn
Definition: captdns.c:50
sint8 espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, uint8 typeflags)
Definition: espconn.c:825
#define NULL
Definition: def.h:47
#define ESPCONN_OK
Definition: espconn.h:20
#define ICACHE_FLASH_ATTR
Definition: c_types.h:99
#define FLAG_TC
Definition: captdns.c:94
bool wifi_get_ip_info(uint8 if_index, struct ip_info *info)
#define FLAG_QR
Definition: captdns.c:92
uint8 remote_ip[4]
Definition: espconn.h:91
static uint16_t ICACHE_FLASH_ATTR my_ntohs(uint16_t *in)
Definition: captdns.c:130
#define QCLASS_IN
Definition: captdns.c:109
static char ICACHE_FLASH_ATTR * strToLabel(char *str, char *label, int maxLen)
Definition: captdns.c:170
static void ICACHE_FLASH_ATTR setn16(void *pp, int16_t n)
Definition: captdns.c:115
#define QTYPE_URI
Definition: captdns.c:107
static char *ICACHE_FLASH_ATTR labelToStr(char *packet, char *labelPtr, int packetSz, char *res, int resMaxLen)
Definition: captdns.c:138
#define QCLASS_URI
Definition: captdns.c:111
unsigned char uint8
Definition: c_types.h:45
DnsUriHdr
Definition: captdns.c:89
int remote_port
Definition: espconn.h:82
#define DNS_LEN
Definition: captdns.c:47
#define ip4_addr3(ipaddr)
Definition: ip_addr.h:222
#define QTYPE_A
Definition: captdns.c:97
union espconn::@1 proto
sint16 ICACHE_FLASH_ATTR espconn_sendto(struct espconn *espconn, uint8 *psent, uint16 length)
Definition: espconn.c:448
#define QTYPE_NS
Definition: captdns.c:98
uint8 remote_ip[4]
Definition: espconn.h:85
DnsResourceFooter
Definition: captdns.c:84
#define memcpy(x, a, b)
Definition: platform.h:22
#define ip4_addr2(ipaddr)
Definition: ip_addr.h:221
#define ip4_addr4(ipaddr)
Definition: ip_addr.h:223
#define ip4_addr1(ipaddr)
Definition: ip_addr.h:220
DnsQuestionFooter
Definition: captdns.c:74
int remote_port
Definition: espconn.h:90
static void ICACHE_FLASH_ATTR captdnsRecv(void *arg, char *pusrdata, unsigned short length)
Definition: captdns.c:192
Here is the call graph for this function:
Here is the caller graph for this function:

◆ captdnsStop()

void ICACHE_FLASH_ATTR captdnsStop ( void  )

Definition at line 353 of file captdns.c.

References espconn_delete().

353  {
355 }
static struct espconn conn
Definition: captdns.c:50
sint8 espconn_delete(struct espconn *espconn)
Definition: espconn.c:1217
Here is the call graph for this function:

◆ labelToStr()

static char* ICACHE_FLASH_ATTR labelToStr ( char *  packet,
char *  labelPtr,
int  packetSz,
char *  res,
int  resMaxLen 
)
static

Definition at line 138 of file captdns.c.

References my_ntohs(), and NULL.

Referenced by captdnsRecv().

138  {
139  int i, j, k;
140  char *endPtr=NULL;
141  i=0;
142  do {
143  if ((*labelPtr&0xC0)==0) {
144  j=*labelPtr++; //skip past length
145  //Add separator period if there already is data in res
146  if (i<resMaxLen && i!=0) res[i++]='.';
147  //Copy label to res
148  for (k=0; k<j; k++) {
149  if ((labelPtr-packet)>packetSz) return NULL;
150  if (i<resMaxLen) res[i++]=*labelPtr++;
151  }
152  } else if ((*labelPtr&0xC0)==0xC0) {
153  //Compressed label pointer
154  endPtr=labelPtr+2;
155  int offset=my_ntohs(((uint16_t *)labelPtr))&0x3FFF;
156  //Check if offset points to somewhere outside of the packet
157  if (offset>packetSz) return NULL;
158  labelPtr=&packet[offset];
159  }
160  //check for out-of-bound-ness
161  if ((labelPtr-packet)>packetSz) return NULL;
162  } while (*labelPtr!=0);
163  res[i]=0; //zero-terminate
164  if (endPtr==NULL) endPtr=labelPtr+1;
165  return endPtr;
166 }
#define NULL
Definition: def.h:47
static uint16_t ICACHE_FLASH_ATTR my_ntohs(uint16_t *in)
Definition: captdns.c:130
Here is the call graph for this function:
Here is the caller graph for this function:

◆ my_ntohs()

static uint16_t ICACHE_FLASH_ATTR my_ntohs ( uint16_t *  in)
static

Definition at line 130 of file captdns.c.

Referenced by captdnsRecv(), and labelToStr().

130  {
131  char *p=(char*)in;
132  return ((p[0]<<8)&0xff00)|(p[1]&0xff);
133 }
Here is the caller graph for this function:

◆ setn16()

static void ICACHE_FLASH_ATTR setn16 ( void *  pp,
int16_t  n 
)
static

Definition at line 115 of file captdns.c.

Referenced by captdnsRecv().

115  {
116  char *p=pp;
117  *p++=(n>>8);
118  *p++=(n&0xff);
119 }
Here is the caller graph for this function:

◆ setn32()

static void ICACHE_FLASH_ATTR setn32 ( void *  pp,
int32_t  n 
)
static

Definition at line 122 of file captdns.c.

Referenced by captdnsRecv().

122  {
123  char *p=pp;
124  *p++=(n>>24)&0xff;
125  *p++=(n>>16)&0xff;
126  *p++=(n>>8)&0xff;
127  *p++=(n&0xff);
128 }
Here is the caller graph for this function:

◆ strToLabel()

static char ICACHE_FLASH_ATTR* strToLabel ( char *  str,
char *  label,
int  maxLen 
)
static

Definition at line 170 of file captdns.c.

Referenced by captdnsRecv().

170  {
171  char *len=label; //ptr to len byte
172  char *p=label+1; //ptr to next label byte to be written
173  while (1) {
174  if (*str=='.' || *str==0) {
175  *len=((p-len)-1); //write len of label bit
176  len=p; //pos of len for next part
177  p++; //data ptr is one past len
178  if (*str==0) break; //done
179  str++;
180  } else {
181  *p++=*str++; //copy byte
182 // if ((p-label)>maxLen) return NULL; //check out of bounds
183  }
184  }
185  *len=0;
186  return p; //ptr to first free byte in resp
187 }
Here is the caller graph for this function:

Variable Documentation

◆ conn

struct espconn conn
static

◆ DnsHeader

DnsHeader

Definition at line 61 of file captdns.c.

Referenced by captdnsRecv().

◆ DnsLabel

DnsLabel

Definition at line 67 of file captdns.c.

◆ DnsQuestionFooter

DnsQuestionFooter

Definition at line 74 of file captdns.c.

Referenced by captdnsRecv().

◆ DnsResourceFooter

DnsResourceFooter

Definition at line 84 of file captdns.c.

Referenced by captdnsRecv().

◆ DnsUriHdr

DnsUriHdr

Definition at line 89 of file captdns.c.

Referenced by captdnsRecv().