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