-
Notifications
You must be signed in to change notification settings - Fork 302
/
main.c
301 lines (259 loc) · 8.16 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h> /* exit() */
#include <ctype.h> /* isspace() */
#ifndef WIN32
#include <sys/types.h>
#include <sys/stat.h>
#else /* WIN32 */
#include <curl/curl.h>
#endif /* WIN32 */
#include "dnsrelated.h"
#include "common.h"
#include "utils.h"
#include "readconfig.h"
#include "querydnsinterface.h"
#define VERSION "2.3"
#define PRINT(...) if(ProgramArgs.ShowMassages == TRUE) printf(__VA_ARGS__);
struct _ProgramArgs
{
char *ConfigFile_ptr;
char ConfigFile[320];
BOOL ShowMassages;
BOOL ErrorMessages;
} ProgramArgs = {
NULL, {0},
TRUE, TRUE,
};
int DaemonInit()
{
#ifdef WIN32
char *CmdLine = GetCommandLine();
char ModuleName[320];
char *itr;
char *NewArguments;
int ModuleNameLength;
BOOL StartUpStatus;
STARTUPINFO StartUpInfo;
PROCESS_INFORMATION ProcessInfo;
ModuleNameLength = GetModuleFileName(NULL, ModuleName, sizeof(ModuleName) - 1);
if( ModuleNameLength == 0 )
{
return 1;
} else {
ModuleName[sizeof(ModuleName) - 1] = '\0';
}
for(; isspace(*CmdLine); ++CmdLine);
if(*CmdLine == '"')
{
itr = strchr(++CmdLine, '"');
} else {
itr = strchr(CmdLine, ' ');
}
if( itr != NULL )
CmdLine = itr + 1;
else
return 1;
for(; isspace(*CmdLine); ++CmdLine);
NewArguments = SafeMalloc(strlen(ModuleName) + strlen(CmdLine) + 32);
strcpy(NewArguments, "\"");
strcat(NewArguments, ModuleName);
strcat(NewArguments, "\" ");
strcat(NewArguments, CmdLine);
itr = strstr(NewArguments + strlen(ModuleName) + 2, "-d");
*(itr + 1) = 'q';
StartUpInfo.cb = sizeof(StartUpInfo);
StartUpInfo.lpReserved = NULL;
StartUpInfo.lpDesktop = NULL;
StartUpInfo.lpTitle = NULL;
StartUpInfo.dwFlags = STARTF_USESHOWWINDOW;
StartUpInfo.wShowWindow = SW_HIDE;
StartUpInfo.cbReserved2 = 0;
StartUpInfo.lpReserved2 = NULL;
StartUpStatus = CreateProcess(NULL, NewArguments, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &StartUpInfo, &ProcessInfo);
SafeFree(NewArguments);
if( StartUpStatus != FALSE )
{
printf("deamon process pid : %d\n", (int)(ProcessInfo.dwProcessId));
exit(0);
} else {
return 1;
}
#else /* WIN32 */
pid_t pid;
if( (pid = fork()) < 0 )
{
return 1;
}
else
{
if(pid != 0)
{
printf("deamon process pid : %d\n", pid);
exit(0);
}
setsid();
umask(0); /* clear file mode creation mask */
close(0);
close(1);
close(2);
return 0;
}
#endif /* WIN32 */
}
int ArgParse(int argc, char *argv_ori[])
{
char **argv = argv_ori;
++argv;
while(*argv != NULL)
{
if(strcmp("-h", *argv) == 0)
{
printf("DNSforwarder by holmium. Free for non-commercial use. Version "VERSION" .\n\n");
printf("Usage : %s [args].\n", strrchr(argv_ori[0], PATH_SLASH_CH) == NULL ? argv_ori[0] : strrchr(argv_ori[0], PATH_SLASH_CH) + 1);
printf(" [args] is case sensitivity and can be zero or more (in any order) of:\n"
" -f <FILE> Use configuration <FILE> instead of the default one.\n"
" -q Quiet mode. Do not print any information.\n"
" -e Only show error messages.\n"
" -d Daemon mode. Run at background.\n"
" -h Show this help.\n"
"\n"
"Output format:\n"
" Date & Time [Udp|Tcp|Cache|Hosts|Refused][Client IP][Type in querying][Domain in query] :\n"
" Results\n"
);
exit(0);
}
if(strcmp("-q", *argv) == 0)
{
ProgramArgs.ShowMassages = FALSE;
ProgramArgs.ErrorMessages = FALSE;
++argv;
continue;
}
if(strcmp("-e", *argv) == 0)
{
ProgramArgs.ShowMassages = FALSE;
++argv;
continue;
}
if(strcmp("-d", *argv) == 0)
{
if(DaemonInit() == 0)
{
ProgramArgs.ShowMassages = FALSE;
} else {
printf("Daemon init failed, continuing non-daemon mode.\n");
}
++argv;
continue;
}
if(strcmp("-f", *argv) == 0)
{
ProgramArgs.ConfigFile_ptr = *(++argv);
++argv;
continue;
}
PRINT("Unrecognisable arg `%s'\n", *argv);
++argv;
}
return 0;
}
int GetDefaultConfigureFile(char *out)
{
#ifdef WIN32
if( GetModuleFileName(NULL, out, 319) != 0 )
{
out[319] = '\0';
strcpy(strrchr(out, '\\') + 1, "dnsforwarder.config");
}
return 0;
#else /* WIN32 */
struct passwd *pw = getpwuid(getuid());
char *home = pw -> pw_dir;
*out = '\0';
if( home == NULL )
return 1;
strcpy(out, home);
strcat(out, "/.dnsforwarder/config");
return 0;
#endif /* WIN32 */
}
int main(int argc, char *argv[])
{
#ifdef WIN32
WSADATA wdata;
#endif
int ret = 0;
#ifdef WIN32
if(WSAStartup(MAKEWORD(2, 2), &wdata) != 0)
return -1;
SetConsoleTitle("dnsforwarder");
#elseif
curl_global_init();
#endif
SafeMallocInit();
ArgParse(argc, argv);
if( ProgramArgs.ConfigFile_ptr == NULL )
{
GetDefaultConfigureFile(ProgramArgs.ConfigFile);
ProgramArgs.ConfigFile_ptr = ProgramArgs.ConfigFile;
}
PRINT("DNSforwarder by holmium. Free for non-commercial use. Version "VERSION" .\n\n");
if( QueryDNSInterfaceInit(ProgramArgs.ConfigFile_ptr, ProgramArgs.ShowMassages, ProgramArgs.ErrorMessages) != 0 )
goto JustEnd;
putchar('\n');
if( QueryDNSInterfaceStart() != 0 )
goto JustEnd;
QueryDNSInterfaceWait();
JustEnd:
#ifdef WIN32
WSACleanup();
#endif
return ret;
}
/*
" -T Open TCP querying at local, no threads specifier.\n"
" -U <NUM> Set the number of UDP querying's threads,\n"
" 0 represents not to use UDP (default 2).\n"
" -s <IP> Specify DNS server which uses TCP for querying.\n"
" -sp <PORT> Specify TCP server's port to <PORT> (default 53).\n"
" -la <IP> Specify local listening IP (default 127.0.0.1).\n"
" -lp <PORT> Specify local port to <PORT> (both UDP and TCP, default 53).\n"
"\n"
"Rule settings (Double-dash):\n"
" --DisableType <NUM1>,<NUM2>,<NUM3>...\n"
" Refuse to query informations with one of those types.\n"
" All types can be get by using arg `--PrintAllTypes'.\n"
" --DisableDomain <DOMAIN1>,<DOMAIN2>,<DOMAIN3>...\n"
" Refuse to query informations with one of those Domains.\n"
" --ExcludeDomain <DOMAIN1>,<DOMAIN2>,<DOMAIN3>...\n"
" Querying those DOMAINs via UDP instead of TCP.\n"
" So arg `--UDPServer' and `--UDPPort' will be essential.\n"
" --InternalExList\n"
" Use internal excluded domains list (Disabled by default).\n"
" The list can be get by using arg `--PrintInExList'.\n"
" --UDPServer <IP>\n"
" Specify DNS server which uses UDP for querying.\n"
" --UDPSPort <PORT>\n"
" Specify UDP server's port (default 53).\n"
"\n"
"Cache Controllings (Double-dash):\n"
" --NoCache Do not use cache (default using).\n"
" --CacheSize <NUM> Specify cache size (in Byte).\n"
" (Default 1048576 Bytes [1MB] ).\n"
" --IgnoreTTL Ignore TTL.\n"
" (do not remove anything from cache, disabled by default)\n"
" --ForceTTL <NUM> Forced let all TTLs be <NUM>,\n"
" instead of their own (default unforced).\n"
" --MultiTTL <NUM> Multiplying TTL by <NUM> (default 1).\n"
"\n"
"Infomations (Double-dash):\n"
" --PrintAllTypes Print all known DNS record types.\n"
" --PrintInExList Print all internal excluded domains.\n"
"\n"
"Other (Double-dash):\n"
" --CustoName <STR> Customising local server name.\n"
"\n"
*/