bugfix: payload ipv6 packets too
[prads.git] / src / sys_func.c
blob500d3db8a1828d6c03e7f6218e7f0d8d1c6b2858
1 #include "common.h"
2 #include "prads.h"
3 #include "sys_func.h"
4 #include "util-cxt.h"
5 #include "assets.h"
6 #include "servicefp/servicefp.h"
7 #include "config.h"
8 #include "sig.h"
9 #include "output-plugins/log.h"
11 #include <libgen.h> // dirname()
13 void free_queue(); // util-cxt.c
14 extern globalconfig config;
16 const char *u_ntop(const struct in6_addr ip_addr, int af, char *dest)
18 if (af == AF_INET) {
19 if (!inet_ntop
20 (AF_INET,
21 &IP4ADDR(&ip_addr),
22 dest, INET_ADDRSTRLEN + 1)) {
23 perror("Something died in inet_ntop");
24 return NULL;
26 } else if (af == AF_INET6) {
27 if (!inet_ntop(AF_INET6, &ip_addr, dest, INET6_ADDRSTRLEN + 1)) {
28 perror("Something died in inet_ntop");
29 return NULL;
32 return dest;
34 const char *u_ntop_dst(packetinfo *pi, char *dest)
36 if (pi->af == AF_INET) {
37 if (!inet_ntop
38 (AF_INET,
39 &pi->ip4->ip_dst,
40 dest, INET_ADDRSTRLEN + 1)) {
41 perror("Something died in inet_ntop");
42 return NULL;
44 } else if (pi->af == AF_INET6) {
45 if (!inet_ntop(AF_INET6, &pi->ip6->ip_dst, dest, INET6_ADDRSTRLEN + 1)) {
46 perror("Something died in inet_ntop");
47 return NULL;
50 return dest;
53 const char *u_ntop_src(packetinfo *pi, char *dest)
55 if (pi->af == AF_INET) {
56 if (!inet_ntop
57 (AF_INET,
58 &pi->ip4->ip_src,
59 dest, INET_ADDRSTRLEN + 1)) {
60 perror("Something died in inet_ntop");
61 return NULL;
63 } else if (pi->af == AF_INET6) {
64 if (!inet_ntop(AF_INET6, &pi->ip6->ip_src, dest, INET6_ADDRSTRLEN + 1)) {
65 perror("Something died in inet_ntop");
66 return NULL;
69 return dest;
72 uint8_t normalize_ttl (uint8_t ttl)
74 if (ttl > 128) return 255;
75 if (ttl > 64) return 128;
76 if (ttl > 32) return 64;
77 else return 32;
80 void bucket_keys_NULL()
82 int cxkey;
83 for (cxkey = 0; cxkey < BUCKET_SIZE; cxkey++) {
84 bucket[cxkey] = NULL;
88 void unload_tcp_sigs()
90 if(config.ctf & CO_SYN && config.sig_syn){
91 unload_sigs(config.sig_syn, config.sig_hashsize);
93 if(config.ctf & CO_SYNACK && config.sig_synack){
94 unload_sigs(config.sig_synack, config.sig_hashsize);
96 if(config.ctf & CO_ACK && config.sig_ack){
97 unload_sigs(config.sig_ack, config.sig_hashsize);
99 if(config.ctf & CO_RST && config.sig_rst){
100 unload_sigs(config.sig_rst, config.sig_hashsize);
102 if(config.ctf & CO_FIN && config.sig_fin){
103 unload_sigs(config.sig_fin, config.sig_hashsize);
107 void print_pcap_stats()
109 if (config.handle == NULL) return;
110 if (pcap_stats(config.handle, &config.ps) == -1) {
111 pcap_perror(config.handle, "pcap_stats");
112 return;
114 olog("-- libpcap:\n");
115 olog("-- Total packets received :%12u\n",config.ps.ps_recv);
116 olog("-- Total packets dropped :%12u\n",config.ps.ps_drop);
117 olog("-- Total packets dropped by Interface :%12u\n",config.ps.ps_ifdrop);
120 int set_chroot(void)
122 char *absdir;
123 //char *logdir;
124 int abslen;
127 * logdir = get_abs_path(logpath);
131 * change to the directory
133 if (chdir(config.chroot_dir) != 0) {
134 elog("set_chroot: Can not chdir to \"%s\": %s\n", config.chroot_dir,
135 strerror(errno));
139 * always returns an absolute pathname
141 absdir = getcwd(NULL, 0);
142 abslen = strlen(absdir);
145 * make the chroot call
147 if (chroot(absdir) < 0) {
148 elog("Can not chroot to \"%s\": absolute: %s: %s\n", config.chroot_dir,
149 absdir, strerror(errno));
150 exit(3);
153 if (chdir("/") < 0) {
154 elog("Can not chdir to \"/\" after chroot: %s\n",
155 strerror(errno));
156 exit(3);
159 return 0;
162 int drop_privs(void)
164 struct group *gr;
165 struct passwd *pw;
166 char *endptr;
167 int i;
168 int do_setuid = 0;
169 int do_setgid = 0;
170 unsigned long groupid = 0;
171 unsigned long userid = 0;
173 if (config.group_name != NULL) {
174 do_setgid = 1;
175 if (!isdigit(config.group_name[0])) {
176 gr = getgrnam(config.group_name);
177 if(!gr){
178 if(config.chroot_dir){
179 elog("ERROR: you have chrootetd and must set numeric group ID.\n");
180 exit(1);
181 }else{
182 elog("ERROR: couldn't get ID for group %s, group does not exist.", config.group_name)
183 exit(1);
186 groupid = gr->gr_gid;
187 } else {
188 groupid = strtoul(config.group_name, &endptr, 10);
192 if (config.user_name != NULL) {
193 do_setuid = 1;
194 do_setgid = 1;
195 if (isdigit(config.user_name[0]) == 0) {
196 pw = getpwnam(config.user_name);
197 if (pw != NULL) {
198 userid = pw->pw_uid;
199 } else {
200 printf("[E] User %s not found!\n", config.user_name);
202 } else {
203 userid = strtoul(config.user_name, &endptr, 10);
204 pw = getpwuid(userid);
207 if (config.group_name == NULL && pw != NULL) {
208 groupid = pw->pw_gid;
212 if (do_setgid) {
213 if ((i = setgid(groupid)) < 0) {
214 printf("Unable to set group ID: %s", strerror(i));
218 endgrent();
219 endpwent();
221 if (do_setuid) {
222 if (getuid() == 0 && initgroups(config.user_name, groupid) < 0) {
223 printf("Unable to init group names (%s/%lu)", config.user_name,
224 groupid);
226 if ((i = setuid(userid)) < 0) {
227 printf("Unable to set user ID: %s\n", strerror(i));
230 return 0;
233 int is_valid_path(const char *path)
235 char dir[STDBUF];
236 struct stat st;
238 if (path == NULL) {
239 return 0;
242 memcpy(dir, path, strnlen(path, STDBUF));
243 dirname(dir);
245 if (stat(dir, &st) != 0) {
246 return 0;
248 if (!S_ISDIR(st.st_mode) || access(dir, W_OK) == -1) {
249 return 0;
251 return 1;
254 int create_pid_file(const char *path)
256 char pid_buffer[12];
257 struct flock lock;
258 int rval;
259 int fd;
261 if (!path) {
262 path = config.pidfile;
264 if (!is_valid_path(path)) {
265 printf("PID path \"%s\" aint writable", path);
268 if ((fd = open(path, O_CREAT | O_WRONLY,
269 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
270 return ERROR;
274 * pid file locking
276 lock.l_type = F_WRLCK;
277 lock.l_start = 0;
278 lock.l_whence = SEEK_SET;
279 lock.l_len = 0;
281 if (fcntl(fd, F_SETLK, &lock) == -1) {
282 if (errno == EACCES || errno == EAGAIN) {
283 rval = ERROR;
284 } else {
285 rval = ERROR;
287 close(fd);
288 return rval;
290 snprintf(pid_buffer, sizeof(pid_buffer), "%d\n", (int)getpid());
291 if (ftruncate(fd, 0) != 0) {
292 return ERROR;
294 if (write(fd, pid_buffer, strlen(pid_buffer)) != 0) {
295 return ERROR;
297 return SUCCESS;
300 int daemonize()
302 pid_t pid;
303 int fd;
305 pid = fork();
307 if (pid > 0) {
308 exit(0); /* parent */
311 config.use_syslog = 1;
312 if (pid < 0) {
313 return ERROR;
317 * new process group
319 setsid();
322 * close file handles
324 if ((fd = open("/dev/null", O_RDWR)) >= 0) {
325 dup2(fd, 0);
326 dup2(fd, 1);
327 dup2(fd, 2);
328 if (fd > 2) {
329 close(fd);
333 if (config.pidfile) {
334 return create_pid_file(config.pidfile);
337 return SUCCESS;
340 char *hex2mac(const uint8_t *mac)
343 static char buf[32];
345 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
346 (mac[0] & 0xFF), (mac[1] & 0xFF), (mac[2] & 0xFF),
347 (mac[3] & 0xFF), (mac[4] & 0xFF), (mac[5] & 0xFF));
349 return buf;