Reformat README to use Markdown
[prads.git] / src / sys_func.c
blobe0c092df4fb94ec91fefa8abbd87ced118aabece
1 #include "common.h"
2 #include "prads.h"
3 #include "sys_func.h"
4 #include "assets.h"
5 #include "servicefp/servicefp.h"
6 #include "config.h"
7 #include "sig.h"
8 #include "output-plugins/log.h"
10 #include <libgen.h> // dirname()
12 void free_queue(); // util-cxt.c
13 extern globalconfig config;
15 const char *u_ntop(const struct in6_addr ip_addr, int af, char *dest)
17 if (af == AF_INET) {
18 if (!inet_ntop
19 (AF_INET,
20 &IP4ADDR(&ip_addr),
21 dest, INET_ADDRSTRLEN + 1)) {
22 perror("Something died in inet_ntop");
23 return NULL;
25 } else if (af == AF_INET6) {
26 if (!inet_ntop(AF_INET6, &ip_addr, dest, INET6_ADDRSTRLEN + 1)) {
27 perror("Something died in inet_ntop");
28 return NULL;
31 return dest;
33 const char *u_ntop_dst(packetinfo *pi, char *dest)
35 if (pi->af == AF_INET) {
36 if (!inet_ntop
37 (AF_INET,
38 &pi->ip4->ip_dst,
39 dest, INET_ADDRSTRLEN + 1)) {
40 perror("Something died in inet_ntop");
41 return NULL;
43 } else if (pi->af == AF_INET6) {
44 if (!inet_ntop(AF_INET6, &pi->ip6->ip_dst, dest, INET6_ADDRSTRLEN + 1)) {
45 perror("Something died in inet_ntop");
46 return NULL;
49 return dest;
52 const char *u_ntop_src(packetinfo *pi, char *dest)
54 if (pi->af == AF_INET) {
55 if (!inet_ntop
56 (AF_INET,
57 &pi->ip4->ip_src,
58 dest, INET_ADDRSTRLEN + 1)) {
59 perror("Something died in inet_ntop");
60 return NULL;
62 } else if (pi->af == AF_INET6) {
63 if (!inet_ntop(AF_INET6, &pi->ip6->ip_src, dest, INET6_ADDRSTRLEN + 1)) {
64 perror("Something died in inet_ntop");
65 return NULL;
68 return dest;
71 uint8_t normalize_ttl (uint8_t ttl)
73 if (ttl > 128) return 255;
74 if (ttl > 64) return 128;
75 if (ttl > 32) return 64;
76 else return 32;
80 void unload_tcp_sigs()
82 if(config.ctf & CO_SYN && config.sig_syn){
83 unload_sigs(config.sig_syn, config.sig_hashsize);
85 if(config.ctf & CO_SYNACK && config.sig_synack){
86 unload_sigs(config.sig_synack, config.sig_hashsize);
88 if(config.ctf & CO_ACK && config.sig_ack){
89 unload_sigs(config.sig_ack, config.sig_hashsize);
91 if(config.ctf & CO_RST && config.sig_rst){
92 unload_sigs(config.sig_rst, config.sig_hashsize);
94 if(config.ctf & CO_FIN && config.sig_fin){
95 unload_sigs(config.sig_fin, config.sig_hashsize);
99 void print_pcap_stats()
101 if (config.handle == NULL) return;
102 if (pcap_stats(config.handle, &config.ps) == -1) {
103 pcap_perror(config.handle, "pcap_stats");
104 return;
106 olog("-- libpcap:\n");
107 olog("-- Total packets received :%12u\n",config.ps.ps_recv);
108 olog("-- Total packets dropped :%12u\n",config.ps.ps_drop);
109 olog("-- Total packets dropped by Interface :%12u\n",config.ps.ps_ifdrop);
112 int set_chroot(void)
114 char *absdir;
115 //char *logdir;
118 * logdir = get_abs_path(logpath);
122 * change to the directory
124 if (chdir(config.chroot_dir) != 0) {
125 elog("set_chroot: Can not chdir to \"%s\": %s\n", config.chroot_dir,
126 strerror(errno));
130 * always returns an absolute pathname
132 absdir = getcwd(NULL, 0);
135 * make the chroot call
137 if (chroot(absdir) < 0) {
138 elog("Can not chroot to \"%s\": absolute: %s: %s\n", config.chroot_dir,
139 absdir, strerror(errno));
140 exit(3);
143 if (chdir("/") < 0) {
144 elog("Can not chdir to \"/\" after chroot: %s\n",
145 strerror(errno));
146 exit(3);
149 return 0;
152 int drop_privs(long userid, long groupid)
154 int i;
156 if ((i = setgid(groupid)) < 0) {
157 elog("[!] Unable to set group ID: %s\n", strerror(i));
158 exit(i);
161 endgrent();
162 endpwent();
164 if (userid) {
165 if ((i = setuid(userid)) < 0) {
166 elog("[!] Unable to set user ID: %s\n", strerror(i));
167 exit(i);
170 return 0;
173 int is_valid_path(const char *path)
175 char dir[STDBUF];
176 struct stat st;
178 if (path == NULL) {
179 return 0;
181 if (stat(path, &st) == 0) {
182 // path already exists. is it regular and writable?
183 if (!S_ISREG(st.st_mode) || access(path, W_OK) != -1) {
184 return 1;
188 strcpy(dir, path);
189 dirname(dir);
191 if (stat(dir, &st) != 0) {
192 return 0;
194 if (!S_ISDIR(st.st_mode) || access(dir, W_OK) == -1) {
195 return 0;
197 return 1;
200 int touch_pid_file(const char *path, long uid, long gid)
202 int fd, rc;
203 fd = open(path, O_CREAT, 0664);
204 if(fd)
205 rc = fchown(fd, uid, gid);
206 close(fd);
207 if(rc || !fd) {
208 elog("Failed to create pid file '%s', %d\n", path,rc);
209 return 666;
211 return 0;
214 long get_gid(const char *group_name)
216 char *endptr;
217 struct group *gr;
219 if(!group_name) return 0;
220 if (!isdigit(group_name[0])) {
221 gr = getgrnam(group_name);
222 if(!gr){
223 elog("ERROR: couldn't get ID for group %s, group does not exist.\n", group_name);
224 return 0;
226 return gr->gr_gid;
228 return strtoul(group_name, &endptr, 10);
231 long get_uid(const char *user_name, int *out_gid)
233 char *endptr;
234 struct passwd *pw;
235 if(!user_name) return 0;
236 if (isdigit(user_name[0]) == 0) {
237 pw = getpwnam(user_name);
238 if (pw != NULL) {
239 if (out_gid)
240 if(*out_gid == 0)
241 *out_gid = pw->pw_gid;
242 return pw->pw_uid;
246 return strtoul(config.user_name, &endptr, 10);
249 int create_pid_file(const char *path)
251 char pid_buffer[12];
252 struct flock lock;
253 int rval;
254 int fd;
256 if (!path) {
257 path = config.pidfile;
259 if (!is_valid_path(path)) {
260 printf("PID path \"%s\" aint writable", path);
263 if ((fd = open(path, O_CREAT | O_WRONLY,
264 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
265 return ERROR;
269 * pid file locking
271 lock.l_type = F_WRLCK;
272 lock.l_start = 0;
273 lock.l_whence = SEEK_SET;
274 lock.l_len = 0;
276 if (fcntl(fd, F_SETLK, &lock) == -1) {
277 if (errno == EACCES || errno == EAGAIN) {
278 rval = errno;
279 } else {
280 rval = ERROR;
282 close(fd);
283 return rval;
285 snprintf(pid_buffer, sizeof(pid_buffer), "%d\n", (int)getpid());
286 if (ftruncate(fd, 0) != 0) {
287 return errno;
289 if (write(fd, pid_buffer, strlen(pid_buffer)) == -1) {
290 return errno;
292 return SUCCESS;
295 int daemonize()
297 pid_t pid;
298 int fd;
300 pid = fork();
302 if (pid > 0) {
303 exit(0); /* parent */
306 if (pid < 0) {
307 return ERROR;
311 * new process group
313 setsid();
316 * close file handles
318 if ((fd = open("/dev/null", O_RDWR)) >= 0) {
319 dup2(fd, 0);
320 dup2(fd, 1);
321 dup2(fd, 2);
322 if (fd > 2) {
323 close(fd);
327 return SUCCESS;
330 char *hex2mac(const uint8_t *mac)
333 static char buf[32];
335 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
336 (mac[0] & 0xFF), (mac[1] & 0xFF), (mac[2] & 0xFF),
337 (mac[3] & 0xFF), (mac[4] & 0xFF), (mac[5] & 0xFF));
339 return buf;