djbdnscurve6  38
djbdnscurve6
dns_ip.c
Go to the documentation of this file.
1 #include "stralloc.h"
2 #include "uint_t.h"
3 #include "byte.h"
4 #include "ip.h"
5 #include "dnsresolv.h"
6 
7 static char *q = 0;
8 
9 int dns_ip4_packet(stralloc *out,const char *buf,unsigned int len)
10 {
11  unsigned int pos;
12  char header[12];
13  uint16 numanswers;
14  uint16 datalen;
15  int ranswers = 0;
16 
17  if (!stralloc_copys(out,"")) return DNS_MEM;
18 
19  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return DNS_ERR;
20  uint16_unpack_big(header + 6,&numanswers);
21  pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
22  pos += 4;
23 
24  while (numanswers--) {
25  pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
26  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return DNS_ERR;
27  uint16_unpack_big(header + 8,&datalen);
28  if (byte_equal(header,2,DNS_T_A))
29  if (byte_equal(header + 2,2,DNS_C_IN))
30  if (datalen == 4) {
31  if (!dns_packet_copy(buf,len,pos,header,4)) return DNS_ERR;
32  if (!stralloc_catb(out,header,4)) return DNS_MEM;
33  }
34  pos += datalen;
35  ++ranswers;
36  }
37 
38  dns_sortip4(out->s,out->len);
39  return ranswers;
40 }
41 
42 int dns_ip4(stralloc *out,stralloc *fqdn)
43 {
44  unsigned int i;
45  char code;
46  char ch;
47  char ip[4];
48  int r;
49  int rc = 0;
50 
51  if (!stralloc_copys(out,"")) return DNS_MEM;
52  if (!stralloc_readyplus(fqdn,1)) return DNS_MEM;
53 
54  fqdn->s[fqdn->len] = 0; /* if FQDN is just IPv4 */
55  if (ip4_scan(fqdn->s,ip)) {
56  if (!stralloc_copyb(out,ip,4)) return DNS_MEM;
57  return 1;
58  }
59 
60  code = 0;
61  for (i = 0; i <= fqdn->len; ++i) {
62  if (i < fqdn->len)
63  ch = fqdn->s[i];
64  else
65  ch = '.';
66 
67  if ((ch == '[') || (ch == ']')) continue;
68  if (ch == '.') {
69  if (!stralloc_append(out,&code)) return DNS_MEM;
70  code = 0;
71  continue;
72  }
73  if ((ch >= '0') && (ch <= '9')) {
74  code *= 10;
75  code += ch - '0';
76  continue;
77  }
78 
79  if (dns_domain_fromdot(&q,fqdn->s,fqdn->len) <= 0) return DNS_ERR; // fdqn -> A query -> response
80  if (dns_resolve(q,DNS_T_A) >= 0) {
83  dns_domain_free(&q);
84  rc += r;
85  }
86 
87  return rc;
88  }
89 
90  out->len &= ~3;
91  return 0;
92 }
93 
94 int dns_ip6_packet(stralloc *out,const char *buf,unsigned int len)
95 {
96  unsigned int pos;
97  char header[16];
98  uint16 numanswers;
99  uint16 datalen;
100  int ranswers = 0;
101 
102  if (!stralloc_copys(out,"")) return DNS_MEM;
103 
104  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return DNS_ERR;
105  uint16_unpack_big(header + 6,&numanswers);
106  pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
107  pos += 4;
108 
109  while (numanswers--) {
110  pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
111  pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return DNS_ERR;
112  uint16_unpack_big(header + 8,&datalen);
113  if (byte_equal(header,2,DNS_T_AAAA)) {
114  if (byte_equal(header + 2,2,DNS_C_IN))
115  if (datalen == 16) {
116  if (!dns_packet_copy(buf,len,pos,header,16)) return DNS_ERR;
117  if (!stralloc_catb(out,header,16)) return DNS_MEM;
118  }
119  } else if (byte_equal(header,2,DNS_T_A))
120  if (byte_equal(header + 2,2,DNS_C_IN))
121  if (datalen == 4) {
122  byte_copy(header,12,V4mappedprefix);
123  if (!dns_packet_copy(buf,len,pos,header + 12,4)) return DNS_ERR;
124  if (!stralloc_catb(out,header,16)) return DNS_MEM;
125  }
126  pos += datalen;
127  ++ranswers;
128  }
129 
130  dns_sortip6(out->s,out->len);
131  return ranswers;
132 }
133 
134 int dns_ip6(stralloc *out,stralloc *fqdn)
135 {
136  unsigned int i;
137  char code;
138  char ch;
139  char ip[16];
140  int r;
141  int rc = 0;
142 
143  if (!stralloc_copys(out,"")) return DNS_MEM;
144  if (!stralloc_readyplus(fqdn,1)) return DNS_MEM;
145 
146  fqdn->s[fqdn->len] = 0; /* if FQDN is just IPv6 */
147  if (ip6_scan(fqdn->s,ip)) {
148  if (!stralloc_copyb(out,ip,16)) return DNS_MEM;
149  return 1;
150  }
151 
152  code = 0;
153  for (i = 0; i <= fqdn->len; ++i) {
154  if (i < fqdn->len)
155  ch = fqdn->s[i];
156  else
157  ch = '.';
158 
159  if ((ch == '[') || (ch == ']')) continue;
160  if (ch == '.') {
161  if (!stralloc_append(out,&code)) return DNS_MEM;
162  code = 0;
163  continue;
164  }
165  if ((ch >= '0') && (ch <= '9')) {
166  code *= 10;
167  code += ch - '0';
168  continue;
169  }
170 
171  if (dns_domain_fromdot(&q,fqdn->s,fqdn->len) <= 0) return DNS_ERR; // fqdn -> AAAA query -> response
172  if (dns_resolve(q,DNS_T_AAAA) >= 0) {
175  dns_domain_free(&q);
176  rc += r;
177  }
178 
179  return rc;
180  }
181 
182  out->len &= ~3;
183  return 0;
184 }
char ip[16]
Definition: axfrdns.c:126
uint16 len
Definition: axfrdns.c:302
char buf[MSGSIZE]
Definition: axfrdns.c:301
void dns_transmit_free(struct dns_transmit *)
Definition: dns_transmit.c:96
void dns_sortip4(char *, unsigned int)
Definition: dns_sortip.c:10
unsigned int dns_packet_copy(const char *, unsigned int, unsigned int, char *, unsigned int)
Definition: dns_packet.c:8
#define DNS_ERR
Definition: dns.h:22
#define DNS_T_A
Definition: dns.h:37
int dns_domain_fromdot(char **, const char *, unsigned int)
Definition: dns_dfd.c:6
#define DNS_C_IN
Definition: dns.h:34
int dns_resolve(const char *, const char *)
void dns_sortip6(char *, unsigned int)
Definition: dns_sortip.c:25
unsigned int dns_packet_skipname(const char *, unsigned int, unsigned int)
Definition: dns_packet.c:18
void dns_domain_free(char **)
Definition: dns_domain.c:17
#define DNS_T_AAAA
Definition: dns.h:48
#define DNS_MEM
Definition: dns.h:21
struct dns_transmit dns_resolve_tx
Definition: dns_resolve.c:7
int dns_ip4_packet(stralloc *out, const char *buf, unsigned int len)
Definition: dns_ip.c:9
int dns_ip6_packet(stralloc *out, const char *buf, unsigned int len)
Definition: dns_ip.c:94
int dns_ip4(stralloc *out, stralloc *fqdn)
Definition: dns_ip.c:42
int dns_ip6(stralloc *out, stralloc *fqdn)
Definition: dns_ip.c:134
void out(const char *s, unsigned int len)
Definition: generic-conf.c:54
unsigned int packetlen
Definition: dns.h:77
char * packet
Definition: dns.h:76