fehQlibs 26
Qlibs
Loading...
Searching...
No Matches
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
14static char *q = 0;
15
16int dns_ip4_packet(stralloc *out,const char *buf,unsigned int len)
17{
18 unsigned int pos;
19 char header[12];
20 uint16 numanswers;
21 uint16 datalen;
22 int ranswers = 0;
23
24 if (!stralloc_copys(out,"")) return DNS_MEM;
25
26 pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return DNS_ERR;
27 uint16_unpack_big(header + 6,&numanswers);
28 pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
29 pos += 4;
30
31 while (numanswers--) {
32 pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
33 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return DNS_ERR;
34 uint16_unpack_big(header + 8,&datalen);
35 if (byte_equal(header,2,DNS_T_A))
36 if (byte_equal(header + 2,2,DNS_C_IN))
37 if (datalen == 4) {
38 if (!dns_packet_copy(buf,len,pos,header,4)) return DNS_ERR;
39 if (!stralloc_catb(out,header,4)) return DNS_MEM;
40 }
41 pos += datalen;
42 ++ranswers;
43 }
44
45 dns_sortip4(out->s,out->len);
46 return ranswers;
47}
48
49int dns_ip4(stralloc *out,stralloc *fqdn)
50{
51 unsigned int i;
52 char code = 0;
53 int dot = 0;
54 char ch;
55 char ip[4];
56 int r;
57 int rc = 0;
58
59 if (!stralloc_copys(out,"")) return DNS_MEM;
60 if (!stralloc_readyplus(fqdn,1)) return DNS_MEM;
61
62 fqdn->s[fqdn->len] = 0; /* test FQDN string */
63 for (i = 1; i < fqdn->len; i++) {
64 if (fqdn->s[i] >= '_') { code = 127; break; }
65 if (fqdn->s[i] == '.') dot++;
66 }
67
68 if (code != 127 && dot == 3) /* if FQDN is just IPv4 */
69 if (ip4_scan(fqdn->s,ip) || ip4_scanbracket(fqdn->s,ip)) {
70 if (!stralloc_copyb(out,ip,4)) return DNS_MEM;
71 return 1;
72 }
73
74 code = 0;
75 for (i = 0; i <= fqdn->len; ++i) {
76 if (i < fqdn->len)
77 ch = fqdn->s[i];
78 else
79 ch = '.';
80
81 if ((ch == '[') || (ch == ']')) continue;
82 if (ch == '.') {
83 if (!stralloc_append(out,&code)) return DNS_MEM;
84 code = 0;
85 continue;
86 }
87 if ((ch >= '0') && (ch <= '9')) {
88 code *= 10;
89 code += ch - '0';
90 continue;
91 }
92
93 if (dns_domain_fromdot(&q,fqdn->s,fqdn->len) <= 0) return DNS_ERR; // fdqn -> A query -> response
94 if (dns_resolve(q,DNS_T_A) >= 0) {
98 rc += r;
99 }
100
101 return rc;
102 }
103
104 out->len &= ~3;
105 return 0;
106}
107
108int dns_ip6_packet(stralloc *out,const char *buf,unsigned int len)
109{
110 unsigned int pos;
111 char header[16];
112 uint16 numanswers;
113 uint16 datalen;
114 int ranswers = 0;
115
116 if (!stralloc_copys(out,"")) return DNS_MEM;
117
118 pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return DNS_ERR;
119 uint16_unpack_big(header + 6,&numanswers);
120 pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
121 pos += 4;
122
123 while (numanswers--) {
124 pos = dns_packet_skipname(buf,len,pos); if (!pos) return DNS_ERR;
125 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return DNS_ERR;
126 uint16_unpack_big(header + 8,&datalen);
127 if (byte_equal(header,2,DNS_T_AAAA)) {
128 if (byte_equal(header + 2,2,DNS_C_IN))
129 if (datalen == 16) {
130 if (!dns_packet_copy(buf,len,pos,header,16)) return DNS_ERR;
131 if (!stralloc_catb(out,header,16)) return DNS_MEM;
132 }
133 } else if (byte_equal(header,2,DNS_T_A))
134 if (byte_equal(header + 2,2,DNS_C_IN))
135 if (datalen == 4) {
136 byte_copy(header,12,V4mappedprefix);
137 if (!dns_packet_copy(buf,len,pos,header + 12,4)) return DNS_ERR;
138 if (!stralloc_catb(out,header,16)) return DNS_MEM;
139 }
140 pos += datalen;
141 ++ranswers;
142 }
143
144 dns_sortip6(out->s,out->len);
145 return ranswers;
146}
147
148int dns_ip6(stralloc *out,stralloc *fqdn)
149{
150 unsigned int i;
151 char code;
152 char ch;
153 char ip[16];
154 int r;
155 int rc = 0;
156
157 if (!stralloc_copys(out,"")) return DNS_MEM;
158 if (!stralloc_readyplus(fqdn,1)) return DNS_MEM;
159
160 fqdn->s[fqdn->len] = 0; /* if FQDN is just IPv6 */
161 if (ip6_scan(fqdn->s,ip) || ip6_scanbracket(fqdn->s,ip)) {
162 if (!stralloc_copyb(out,ip,16)) return DNS_MEM;
163 return 1;
164 }
165
166 code = 0;
167 for (i = 0; i <= fqdn->len; ++i) {
168 if (i < fqdn->len)
169 ch = fqdn->s[i];
170 else
171 ch = '.';
172
173 if ((ch == '[') || (ch == ']')) continue;
174 if (ch == '.') {
175 if (!stralloc_append(out,&code)) return DNS_MEM;
176 code = 0;
177 continue;
178 }
179 if ((ch >= '0') && (ch <= '9')) {
180 code *= 10;
181 code += ch - '0';
182 continue;
183 }
184
185 if (dns_domain_fromdot(&q,fqdn->s,fqdn->len) <= 0) return DNS_ERR; // fqdn -> AAAA query -> response
186 if (dns_resolve(q,DNS_T_AAAA) >= 0) {
189 dns_domain_free(&q);
190 rc += r;
191 }
192
193 return rc;
194 }
195
196 out->len &= ~3;
197 return 0;
198}
const unsigned char V4mappedprefix[12]
Definition: socket_if.c:18
int dns_ip4_packet(stralloc *out, const char *buf, unsigned int len)
Definition: dns_ip.c:16
int dns_ip6_packet(stralloc *out, const char *buf, unsigned int len)
Definition: dns_ip.c:108
int dns_ip4(stralloc *out, stralloc *fqdn)
Definition: dns_ip.c:49
int dns_ip6(stralloc *out, stralloc *fqdn)
Definition: dns_ip.c:148
additional types and pack routines
uint16_t uint16
Definition: uint_t.h:29
void uint16_unpack_big(char[16], uint16 *)
unsigned int ip4_scanbracket(const char *, char[4])
ip4_scanbracket parse IPv4 address string enclosed in brackets and convert to IP address array
Definition: ip4.c:92
unsigned int ip4_scan(const char *, char[4])
ip4_scan parse IPv4 address string and convert to IP address array
Definition: ip4.c:67
unsigned int ip6_scan(const char *, char[16])
ip6_scan parse compactified IPv6 address string and convert to IPv6 address array
Definition: ip6.c:151
unsigned int ip6_scanbracket(const char *, char[16])
ip6_scanbracket parse IPv6 string address enclosed in brackets
Definition: ip6.c:243
void byte_copy(void *, unsigned int, const void *)
Definition: byte.c:20
#define byte_equal(s, n, t)
Definition: byte.h:18
void dns_transmit_free(struct dns_transmit *)
Definition: dns_transmit.c:105
void dns_sortip4(char *, unsigned int)
Definition: dns_sortip.c:17
unsigned int dns_packet_copy(const char *, unsigned int, unsigned int, char *, unsigned int)
Definition: dns_packet.c:12
#define DNS_ERR
Definition: dnsresolv.h:44
#define DNS_T_A
Definition: dnsresolv.h:63
int dns_domain_fromdot(char **, const char *, unsigned int)
Definition: dns_dfd.c:13
#define DNS_C_IN
Definition: dnsresolv.h:60
int dns_resolve(const char *, const char *)
void dns_sortip6(char *, unsigned int)
Definition: dns_sortip.c:32
unsigned int dns_packet_skipname(const char *, unsigned int, unsigned int)
Definition: dns_packet.c:22
void dns_domain_free(char **)
Definition: dns_domain.c:24
#define DNS_T_AAAA
Definition: dnsresolv.h:74
#define DNS_MEM
Definition: dnsresolv.h:43
struct dns_transmit dns_resolve_tx
Definition: dns_resolve.c:14
int stralloc_catb(stralloc *, const char *, unsigned int)
Definition: stralloc.c:26
int stralloc_append(stralloc *sa, const char *in)
Definition: stralloc.c:112
int stralloc_copyb(stralloc *, const char *, unsigned int)
Definition: stralloc.c:70
int stralloc_readyplus(stralloc *sa, size_t len)
Definition: stralloc.c:61
int stralloc_copys(stralloc *, const char *)
Definition: stralloc.c:79
unsigned int packetlen
Definition: dnsresolv.h:103
char * packet
Definition: dnsresolv.h:102
size_t len
Definition: stralloc.h:19
char * s
Definition: stralloc.h:18