1 #include <string.h>
2 #include "iheader.h"
3 #include "dnsparser.h"
4 #include "dnsgenerator.h"
5 #include "common.h"
6 #include "logs.h"
7
8 static BOOL ap = FALSE;
9
IHeader_Init(BOOL _ap)10 int IHeader_Init(BOOL _ap)
11 {
12 ap = _ap;
13
14 return 0;
15 }
16
IHeader_Reset(IHeader * h)17 void IHeader_Reset(IHeader *h)
18 {
19 h->_Pad = 0;
20 h->Agent[0] = '\0';
21 h->BackAddress.family = AF_UNSPEC;
22 h->Domain[0] = '\0';
23 h->EDNSEnabled = FALSE;
24 }
25
IHeader_Fill(IHeader * h,BOOL ReturnHeader,char * DnsEntity,int EntityLength,struct sockaddr * BackAddress,SOCKET SendBackSocket,sa_family_t Family,const char * Agent)26 int IHeader_Fill(IHeader *h,
27 BOOL ReturnHeader, /* For tcp, this will be ignored */
28 char *DnsEntity,
29 int EntityLength,
30 struct sockaddr *BackAddress, /* NULL for tcp */
31 SOCKET SendBackSocket,
32 sa_family_t Family, /* For tcp, this will be ignored */
33 const char *Agent
34 )
35 {
36 DnsSimpleParser p;
37 DnsSimpleParserIterator i;
38
39 h->_Pad = 0;
40 h->EDNSEnabled = FALSE;
41
42 if( DnsSimpleParser_Init(&p, DnsEntity, EntityLength, FALSE) != 0 )
43 {
44 return -31;
45 }
46
47 if( DnsSimpleParserIterator_Init(&i, &p) != 0 )
48 {
49 return -36;
50 }
51
52 while( i.Next(&i) != NULL )
53 {
54 switch( i.Purpose )
55 {
56 case DNS_RECORD_PURPOSE_QUESTION:
57 if( i.Klass != DNS_CLASS_IN )
58 {
59 return -48;
60 }
61
62 if( i.GetName(&i, h->Domain, sizeof(h->Domain)) < 0 )
63 {
64 return -46;
65 }
66
67 StrToLower(h->Domain);
68 h->HashValue = ELFHash(h->Domain, 0);
69 h->Type = (DNSRecordType)DNSGetRecordType(DNSJumpHeader(DnsEntity));
70 break;
71
72 case DNS_RECORD_PURPOSE_ADDITIONAL:
73 if( i.Type == DNS_TYPE_OPT )
74 {
75 h->EDNSEnabled = TRUE;
76 }
77 break;
78
79 default:
80 break;
81 }
82 }
83
84 h->ReturnHeader = ReturnHeader;
85
86 if( BackAddress != NULL )
87 {
88 memcpy(&(h->BackAddress.Addr), BackAddress, GetAddressLength(Family));
89 h->BackAddress.family = Family;
90 } else {
91 h->BackAddress.family = AF_UNSPEC;
92 }
93
94 h->SendBackSocket = SendBackSocket;
95
96 if( Agent != NULL )
97 {
98 strncpy(h->Agent, Agent, sizeof(h->Agent));
99 h->Agent[sizeof(h->Agent) - 1] = '\0';
100 } else {
101 h->Agent[0] = '\0';
102 }
103
104 h->EntityLength = EntityLength;
105
106 return 0;
107 }
108
IHeader_AddFakeEdns(IHeader * h,int BufferLength)109 int IHeader_AddFakeEdns(IHeader *h, int BufferLength)
110 {
111 DnsGenerator g;
112
113 if( ap == FALSE || h->EDNSEnabled )
114 {
115 return 0;
116 }
117
118 if( DnsGenerator_Init(&g,
119 IHEADER_TAIL(h),
120 BufferLength - sizeof(IHeader),
121 IHEADER_TAIL(h),
122 h->EntityLength,
123 FALSE
124 )
125 != 0 )
126 {
127 return -125;
128 }
129
130 while( g.NextPurpose(&g) != DNS_RECORD_PURPOSE_ADDITIONAL );
131
132 g.EDns(&g, 1280);
133
134 h->EntityLength = g.Length(&g);
135 h->EDNSEnabled = TRUE;
136
137 return 0;
138 }
139
IHeader_Blocked(IHeader * h)140 BOOL IHeader_Blocked(IHeader *h /* Entity followed */)
141 {
142 return (ap && !(h->EDNSEnabled));
143 }
144
IHeader_SendBack(IHeader * h)145 int IHeader_SendBack(IHeader *h /* Entity followed */)
146 {
147 if( h->BackAddress.family == AF_UNSPEC )
148 {
149 /* TCP */
150 uint16_t TcpLength = htons(h->EntityLength);
151
152 memcpy((char *)(IHEADER_TAIL(h)) - 2, &TcpLength, 2);
153
154 if( send(h->SendBackSocket,
155 (char *)(IHEADER_TAIL(h)) - 2,
156 h->EntityLength + 2,
157 MSG_NOSIGNAL
158 )
159 != h->EntityLength )
160 {
161 /** TODO: Show error */
162 return -112;
163 }
164 } else {
165 /* UDP */
166 const char *Content;
167 int Length;
168
169 if( h->ReturnHeader )
170 {
171 Content = (const char *)h;
172 Length = h->EntityLength + sizeof(IHeader);
173 } else {
174 Content = IHEADER_TAIL(h);
175 Length = h->EntityLength;
176 }
177
178 if( sendto(h->SendBackSocket,
179 Content,
180 Length,
181 MSG_NOSIGNAL,
182 (const struct sockaddr *)&(h->BackAddress.Addr),
183 GetAddressLength(h->BackAddress.family)
184 )
185 != Length )
186 {
187 /** TODO: Show error */
188 return -138;
189 }
190 }
191
192 return 0;
193 }
194
IHeader_SendBackRefusedMessage(IHeader * h)195 int IHeader_SendBackRefusedMessage(IHeader *h)
196 {
197 DNSHeader *RequestContent = IHEADER_TAIL(h);
198
199 RequestContent->Flags.Direction = 1;
200 RequestContent->Flags.RecursionAvailable = 1;
201 RequestContent->Flags.ResponseCode = 0;
202
203 return IHeader_SendBack(h);
204
205 }
206