source: trunk/src/sh_port2proc.c@ 201

Last change on this file since 201 was 199, checked in by katerina, 16 years ago

While we're at it, implement 'else' cor the config file conditionals. Also fix some compile warnings and improve docs.

File size: 23.3 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 2008 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/types.h>
26#include <unistd.h>
27
28#ifdef HAVE_DIRENT_H
29#include <dirent.h>
30#define NAMLEN(dirent) sl_strlen((dirent)->d_name)
31#else
32#define dirent direct
33#define NAMLEN(dirent) (dirent)->d_namlen
34#ifdef HAVE_SYS_NDIR_H
35#include <sys/ndir.h>
36#endif
37#ifdef HAVE_SYS_DIR_H
38#include <sys/dir.h>
39#endif
40#ifdef HAVE_NDIR_H
41#include <ndir.h>
42#endif
43#endif
44#define NEED_ADD_DIRENT
45
46#if defined(SH_USE_PORTCHECK) && (defined (SH_WITH_CLIENT) || defined (SH_STANDALONE))
47
48/****************************************************************************
49 *
50 * >>> COMMON CODE <<<
51 *
52 ****************************************************************************/
53#if defined(__linux__) || defined(__FreeBSD__)
54
55#include "samhain.h"
56#include "sh_error_min.h"
57#include "sh_utils.h"
58#include "sh_pthread.h"
59
60#define FIL__ _("sh_port2proc.c")
61
62struct sock_store {
63 unsigned long sock;
64 size_t pid;
65 char * path;
66 char * user;
67 struct sock_store * next;
68};
69
70/* /proc:
71 * linux: /proc/pid/exe
72 * freebsd: /proc/pid/file
73 * solaris10: /proc/pid/path/a.out
74 */
75static void get_user_and_path (struct sock_store * add)
76{
77 extern char * sh_unix_getUIDname (int level, uid_t uid, char * out, size_t len);
78
79 char path[128];
80 char * buf;
81 struct stat sbuf;
82 int len;
83 char * tmp;
84
85 sl_snprintf (path, sizeof(path), "/proc/%ld/exe", (unsigned long) add->pid);
86
87 if (0 == retry_lstat(FIL__, __LINE__, path, &sbuf) && S_ISLNK(sbuf.st_mode))
88 {
89 goto linkread;
90 }
91
92 sl_snprintf (path, sizeof(path), "/proc/%ld/file", (unsigned long) add->pid);
93
94 if (0 == retry_lstat(FIL__, __LINE__, path, &sbuf) && S_ISLNK(sbuf.st_mode))
95 {
96 goto linkread;
97 }
98
99 sl_snprintf (path, sizeof(path), "/proc/%ld/path/a.out", (unsigned long) add->pid);
100
101 if (0 == retry_lstat(FIL__, __LINE__, path, &sbuf) && S_ISLNK(sbuf.st_mode))
102 {
103 goto linkread;
104 }
105
106 return;
107
108 linkread:
109
110 buf = SH_ALLOC(PATH_MAX);
111 len = readlink(path, buf, PATH_MAX); /* flawfinder: ignore */
112 len = (len >= PATH_MAX) ? (PATH_MAX-1) : len;
113
114 if (len > 0)
115 {
116 buf[len] = '\0';
117 add->path = buf;
118 }
119 else
120 {
121 SH_FREE(buf);
122 }
123
124 add->user = SH_ALLOC(USER_MAX);
125 tmp = sh_unix_getUIDname (SH_ERR_ALL, sbuf.st_uid, add->user, USER_MAX);
126
127 if (!tmp)
128 sl_snprintf (add->user, USER_MAX, "%ld", (unsigned long) sbuf.st_uid);
129
130 return;
131}
132
133#endif
134
135/****************************************************************************
136 *
137 * >>> LINUX CODE <<<
138 *
139 ****************************************************************************/
140
141#if defined(__linux__)
142
143static size_t sh_minpid = 0x0001;
144static size_t sh_maxpid = 0x8000;
145
146#ifndef HAVE_LSTAT
147#define lstat(x,y) stat(x,y)
148#endif /* HAVE_LSTAT */
149
150#if defined(S_IFLNK) && !defined(S_ISLNK)
151# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
152#else
153# if !defined(S_ISLNK)
154# define S_ISLNK(mode) (0)
155# endif
156#endif
157
158#if defined(__linux__)
159#define PROC_PID_MAX _("/proc/sys/kernel/pid_max")
160
161static int proc_max_pid (size_t * procpid)
162{
163 char * ret;
164 unsigned long pid;
165 FILE * fd;
166 char str[128];
167 char * ptr;
168
169 SL_ENTER(_("proc_max_pid"));
170
171 if (0 == access(PROC_PID_MAX, R_OK)) /* flawfinder: ignore */
172 {
173 if (NULL != (fd = fopen(PROC_PID_MAX, "r")))
174 {
175 str[0] = '\0';
176 ret = fgets(str, 128, fd);
177 if (ret && *str != '\0')
178 {
179 pid = strtoul(str, &ptr, 0);
180 if (*ptr == '\0' || *ptr == '\n')
181 {
182 fclose(fd);
183 *procpid = (size_t) pid;
184 SL_RETURN(0, _("proc_max_pid"));
185 }
186 }
187 fclose(fd);
188 }
189 }
190 SL_RETURN((-1), _("proc_max_pid"));
191}
192#else
193static int proc_max_pid(size_t * procpid)
194{
195 *procpid = sh_maxpid;
196 return 0;
197}
198#endif
199
200static struct sock_store * socklist = NULL;
201
202static void del_sock_all()
203{
204 struct sock_store * del = socklist;
205
206 while (del)
207 {
208 socklist = del->next;
209 if (del->path)
210 SH_FREE(del->path);
211 if (del->user)
212 SH_FREE(del->user);
213 SH_FREE(del);
214 del = socklist;
215 }
216 socklist = NULL;
217 return;
218}
219
220static void add_sock(unsigned long sock, size_t pid)
221{
222 struct sock_store * add = SH_ALLOC(sizeof(struct sock_store));
223
224 add->sock = sock;
225 add->pid = pid;
226 add->path = NULL;
227 add->user = NULL;
228 SH_MUTEX_LOCK(mutex_thread_nolog);
229 get_user_and_path(add);
230 SH_MUTEX_UNLOCK(mutex_thread_nolog);
231 add->next = socklist;
232 socklist = add;
233 return;
234}
235
236static void check_and_add_sock(char * fbuf, size_t pid)
237{
238 if (0 == strncmp(_("socket:["), fbuf, 8))
239 {
240 char * end;
241 unsigned long sock;
242 size_t len = strlen(fbuf);
243 if (fbuf[len-1] == ']')
244 fbuf[len-1] = '\0';
245 sock = strtoul(&fbuf[8], &end, 0);
246 if (*end == '\0' && fbuf[8] != '\0')
247 {
248 add_sock(sock, pid);
249 }
250 }
251}
252
253static void fetch_socks(size_t pid)
254{
255 char path[128];
256 DIR * dir;
257 sl_snprintf(path, sizeof(path), _("/proc/%lu/fd"), (unsigned long) pid);
258
259 dir = opendir(path);
260 if (dir)
261 {
262 struct dirent *entry;
263 while (NULL != (entry = readdir(dir)))
264 {
265 char fpath[384];
266 char fbuf[64];
267 int ret;
268 /* /proc/PID/fd/N-> socket:[15713] */
269 sl_snprintf(fpath, sizeof(fpath), _("%s/%s"), path, entry->d_name);
270 ret = readlink(fpath, fbuf, sizeof(fbuf)-1); /* flawfinder: ignore */
271 if (ret > 0)
272 {
273 fbuf[ret] = '\0';
274 check_and_add_sock(fbuf, pid);
275 }
276 }
277 closedir(dir);
278 }
279}
280
281int sh_port2proc_prepare()
282{
283 size_t i;
284
285 if (0 != proc_max_pid(&sh_maxpid))
286 {
287 SH_MUTEX_LOCK(mutex_thread_nolog);
288 sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, 0, MSG_E_SUBGEN,
289 _("Failed to detect max_pid"),
290 _("sh_port2proc"));
291 SH_MUTEX_UNLOCK(mutex_thread_nolog);
292 SL_RETURN ((-1), _("sh_port2proc"));
293 }
294
295 /* Delete old socket list and re-create it
296 */
297 del_sock_all();
298
299 for (i = sh_minpid; i < sh_maxpid; ++i)
300 {
301 fetch_socks(i);
302 }
303
304 return 0;
305}
306
307#include <sys/socket.h>
308#include <netinet/in.h>
309#include <arpa/inet.h>
310
311/* returns the command and fills the 'user' array
312 */
313char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
314 char * user, size_t userlen)
315{
316 FILE * fd;
317
318 if (proto == IPPROTO_TCP)
319 fd = fopen("/proc/net/tcp", "r");
320 else
321 fd = fopen("/proc/net/udp", "r");
322
323 if (fd)
324 {
325 int n, iface, port, inode;
326 char line[512];
327
328 while (NULL != fgets(line, sizeof(line), fd))
329 {
330
331 if (4 == sscanf(line,
332 "%d: %X:%X %*X:%*X %*X %*X:%*X %*X:%*X %*X %*d %*d %d %*s",
333 &n, &iface, &port, &inode))
334 {
335 struct in_addr haddr;
336 haddr.s_addr = (unsigned long)iface;
337
338 if (haddr.s_addr == saddr->s_addr && port == sport)
339 {
340 struct sock_store * new = socklist;
341
342 while (new)
343 {
344 if ((unsigned int)inode == new->sock)
345 {
346 fclose(fd);
347 if (new->path)
348 {
349 if (new->user)
350 sl_strlcpy(user, new->user, userlen);
351 else
352 sl_strlcpy(user, "-", userlen);
353 return sh_util_strdup(new->path);
354 }
355 goto err_out;
356 }
357 new = new->next;
358 }
359 }
360 }
361 }
362 fclose(fd);
363 }
364 err_out:
365 sl_strlcpy(user, "0", userlen);
366 return sh_util_strdup("-");
367}
368
369
370/****************************************************************************
371 *
372 * >>> FREEBSD CODE <<<
373 *
374 ****************************************************************************/
375
376#elif defined(__FreeBSD__)
377
378/* Uses code from sockstat.c. Error and memory handling modified.
379 * Only required functions from sockstat.c are included.
380 */
381
382/*-
383 * Copyright (c) 2002 Dag-Erling Co<EF>dan Sm<F8>rgrav
384 * All rights reserved.
385 *
386 * Redistribution and use in source and binary forms, with or without
387 * modification, are permitted provided that the following conditions
388 * are met:
389 * 1. Redistributions of source code must retain the above copyright
390 * notice, this list of conditions and the following disclaimer
391 * in this position and unchanged.
392 * 2. Redistributions in binary form must reproduce the above copyright
393 * notice, this list of conditions and the following disclaimer in the
394 * documentation and/or other materials provided with the distribution.
395 * 3. The name of the author may not be used to endorse or promote products
396 * derived from this software without specific prior written permission.
397 *
398 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
399 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
400 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
401 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
402 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
403 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
404 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
405 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
406 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
407 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
408 */
409#include <sys/cdefs.h>
410__FBSDID("$FreeBSD: src/usr.bin/sockstat/sockstat.c,v 1.13.2.1.4.1 2008/10/02 02:57:24 kensmith Exp $");
411
412#include <sys/param.h>
413#include <sys/socket.h>
414#include <sys/socketvar.h>
415#include <sys/sysctl.h>
416#include <sys/file.h>
417#include <sys/user.h>
418
419#include <sys/un.h>
420#include <sys/unpcb.h>
421
422#include <net/route.h>
423
424#include <netinet/in.h>
425#include <netinet/in_pcb.h>
426#include <netinet/tcp.h>
427#include <netinet/tcp_seq.h>
428#include <netinet/tcp_var.h>
429#include <arpa/inet.h>
430
431#include <ctype.h>
432#include <errno.h>
433#include <netdb.h>
434#include <stdio.h>
435#include <stdlib.h>
436
437#include <unistd.h>
438
439static int opt_4 = 1; /* Show IPv4 sockets */
440static int opt_6 = 0; /* Show IPv6 sockets */
441static int opt_c = 0; /* Show connected sockets */
442static int opt_l = 1; /* Show listening sockets */
443static int opt_v = 0; /* Verbose mode */
444
445struct sock {
446 void *socket;
447 void *pcb;
448 int vflag;
449 int family;
450 int proto;
451
452 struct sockaddr_storage laddr;
453 struct sockaddr_storage faddr;
454 struct sock *next;
455};
456
457#define HASHSIZE 1009
458static struct sock *sockhash[HASHSIZE];
459
460static struct xfile *xfiles;
461static int nxfiles;
462
463
464static void * xrealloc(void * buf, size_t len0, size_t len)
465{
466 if (len > 0)
467 {
468 void * xbuf = SH_ALLOC(len);
469 if (buf)
470 {
471 if (len0 <= len)
472 memcpy(xbuf, buf, len0);
473 else
474 memset(xbuf, '\0', len);
475 SH_FREE(buf);
476 }
477 return xbuf;
478 }
479 SH_FREE(buf);
480 return NULL;
481}
482
483/* Sets address and port in struct sockaddr_storage *sa
484 */
485static void
486sockaddr(struct sockaddr_storage *sa, int af, void *addr, int port)
487{
488 struct sockaddr_in *sin4;
489 struct sockaddr_in6 *sin6;
490
491 bzero(sa, sizeof *sa);
492 switch (af) {
493 case AF_INET:
494 sin4 = (struct sockaddr_in *)sa;
495 sin4->sin_len = sizeof *sin4;
496 sin4->sin_family = af;
497 sin4->sin_port = port;
498 sin4->sin_addr = *(struct in_addr *)addr;
499 break;
500 case AF_INET6:
501 sin6 = (struct sockaddr_in6 *)sa;
502 sin6->sin6_len = sizeof *sin6;
503 sin6->sin6_family = af;
504 sin6->sin6_port = port;
505 sin6->sin6_addr = *(struct in6_addr *)addr;
506 break;
507 default:
508 return;
509 }
510}
511
512/* Get socket information from the kernel.
513 */
514static void
515gather_inet(int proto)
516{
517 struct xinpgen *xig, *exig;
518 struct xinpcb *xip;
519 struct xtcpcb *xtp;
520 struct inpcb *inp;
521 struct xsocket *so;
522 struct sock *sock;
523 char varname[32];
524 size_t len, bufsize, bufsize0;
525 void *buf;
526 int hash, retry, vflag;
527
528 vflag = 0;
529 if (opt_4)
530 vflag |= INP_IPV4;
531 if (opt_6)
532 vflag |= INP_IPV6;
533
534 switch (proto) {
535 case IPPROTO_TCP:
536 sl_strlcpy(varname, _("net.inet.tcp.pcblist"), sizeof(varname));
537 break;
538 case IPPROTO_UDP:
539 sl_strlcpy(varname, _("net.inet.udp.pcblist"), sizeof(varname));
540 break;
541 case IPPROTO_DIVERT:
542 sl_strlcpy(varname, _("net.inet.divert.pcblist"), sizeof(varname));
543 break;
544 default:
545 return;
546 }
547
548 buf = NULL;
549 bufsize = 8192;
550 bufsize0 = bufsize;
551 retry = 5;
552 do {
553 for (;;) {
554 buf = xrealloc(buf, bufsize0, bufsize);
555 bufsize0 = bufsize;
556 len = bufsize;
557 if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
558 break;
559 if (errno == ENOENT)
560 goto out;
561 if (errno != ENOMEM)
562 {
563 SH_MUTEX_LOCK(mutex_thread_nolog);
564 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__,
565 0, MSG_E_SUBGEN,
566 _("sysctlbyname()"),
567 _("gather_inet"));
568 SH_MUTEX_UNLOCK(mutex_thread_nolog);
569 SH_FREE(buf);
570 return;
571 }
572 bufsize *= 2;
573 }
574 xig = (struct xinpgen *)buf;
575 exig = (struct xinpgen *)(void *)
576 ((char *)buf + len - sizeof *exig);
577 if (xig->xig_len != sizeof *xig ||
578 exig->xig_len != sizeof *exig)
579 {
580 SH_MUTEX_LOCK(mutex_thread_nolog);
581 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
582 _("struct xinpgen size mismatch"),
583 _("gather_inet"));
584 SH_MUTEX_UNLOCK(mutex_thread_nolog);
585 goto out;
586 }
587
588 } while (xig->xig_gen != exig->xig_gen && retry--);
589
590 if (xig->xig_gen != exig->xig_gen && opt_v)
591 {
592 SH_MUTEX_LOCK(mutex_thread_nolog);
593 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN,
594 _("data may be inconsistent"),
595 _("gather_inet"));
596 SH_MUTEX_UNLOCK(mutex_thread_nolog);
597 }
598
599 for (;;) {
600 xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len);
601 if (xig >= exig)
602 break;
603 switch (proto) {
604 case IPPROTO_TCP:
605 xtp = (struct xtcpcb *)xig;
606 if (xtp->xt_len != sizeof *xtp) {
607 SH_MUTEX_LOCK(mutex_thread_nolog);
608 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN,
609 _("struct xtcpcb size mismatch"),
610 _("gather_inet"));
611 SH_MUTEX_UNLOCK(mutex_thread_nolog);
612 goto out;
613 }
614 inp = &xtp->xt_inp;
615 so = &xtp->xt_socket;
616 break;
617 case IPPROTO_UDP:
618 case IPPROTO_DIVERT:
619 xip = (struct xinpcb *)xig;
620 if (xip->xi_len != sizeof *xip) {
621 SH_MUTEX_LOCK(mutex_thread_nolog);
622 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN,
623 _("struct xinpcb size mismatch"),
624 _("gather_inet"));
625 SH_MUTEX_UNLOCK(mutex_thread_nolog);
626 goto out;
627 }
628 inp = &xip->xi_inp;
629 so = &xip->xi_socket;
630 break;
631 default:
632 return;
633 }
634 if ((inp->inp_vflag & vflag) == 0)
635 continue;
636 if (inp->inp_vflag & INP_IPV4) {
637 if ((inp->inp_fport == 0 && !opt_l) ||
638 (inp->inp_fport != 0 && !opt_c))
639 continue;
640 } else if (inp->inp_vflag & INP_IPV6) {
641 if ((inp->in6p_fport == 0 && !opt_l) ||
642 (inp->in6p_fport != 0 && !opt_c))
643 continue;
644 } else {
645 if (opt_v) {
646 char errmsg[64];
647 sl_snprintf(errmsg, sizeof(errmsg),
648 _("invalid vflag 0x%x"), inp->inp_vflag);
649 SH_MUTEX_LOCK(mutex_thread_nolog);
650 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, 0, MSG_E_SUBGEN,
651 errmsg,
652 _("gather_inet"));
653 SH_MUTEX_UNLOCK(mutex_thread_nolog);
654 continue;
655 }
656 }
657
658 sock = SH_ALLOC(sizeof *sock);
659 memset(sock, '\0', sizeof (*sock));
660
661 sock->socket = so->xso_so;
662 sock->proto = proto;
663 if (inp->inp_vflag & INP_IPV4) {
664 sock->family = AF_INET;
665 sockaddr(&sock->laddr, sock->family,
666 &inp->inp_laddr, inp->inp_lport);
667 sockaddr(&sock->faddr, sock->family,
668 &inp->inp_faddr, inp->inp_fport);
669 } else if (inp->inp_vflag & INP_IPV6) {
670 sock->family = AF_INET6;
671 sockaddr(&sock->laddr, sock->family,
672 &inp->in6p_laddr, inp->in6p_lport);
673 sockaddr(&sock->faddr, sock->family,
674 &inp->in6p_faddr, inp->in6p_fport);
675 }
676 sock->vflag = inp->inp_vflag;
677
678 hash = (int)((uintptr_t)sock->socket % HASHSIZE);
679 sock->next = sockhash[hash];
680 sockhash[hash] = sock;
681 }
682out:
683 if (buf)
684 SH_FREE(buf);
685}
686
687static void
688getfiles(void)
689{
690 size_t len;
691 size_t len0;
692
693 xfiles = SH_ALLOC(len = sizeof *xfiles);
694 len0 = len;
695
696 while (sysctlbyname(_("kern.file"), xfiles, &len, 0, 0) == -1) {
697 if (errno != ENOMEM)
698 {
699 volatile int status = errno;
700 SH_MUTEX_LOCK(mutex_thread_nolog);
701 sh_error_handle((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
702 _("sysctlbyname()"),
703 _("getfiles"));
704 SH_MUTEX_UNLOCK(mutex_thread_nolog);
705 }
706 len *= 2;
707 xfiles = xrealloc(xfiles, len0, len);
708 len0 = len;
709 }
710 if (len > 0 && xfiles->xf_size != sizeof *xfiles)
711 if (errno != ENOMEM)
712 {
713 volatile int status = errno;
714 SH_MUTEX_LOCK(mutex_thread_nolog);
715 sh_error_handle((-1), FIL__, __LINE__, status, MSG_E_SUBGEN,
716 _("struct xfile size mismatch"),
717 _("getfiles"));
718 SH_MUTEX_UNLOCK(mutex_thread_nolog);
719 }
720 nxfiles = len / sizeof *xfiles;
721}
722
723static const char *
724getprocname(pid_t pid)
725{
726 static struct kinfo_proc proc;
727 size_t len;
728 int mib[4];
729
730 mib[0] = CTL_KERN;
731 mib[1] = KERN_PROC;
732 mib[2] = KERN_PROC_PID;
733 mib[3] = (int)pid;
734 len = sizeof proc;
735 if (sysctl(mib, 4, &proc, &len, NULL, 0) == -1) {
736 /* Do not warn if the process exits before we get its name. */
737 if (errno != ESRCH)
738 {
739 volatile int status = errno;
740 SH_MUTEX_LOCK(mutex_thread_nolog);
741 sh_error_handle(SH_ERR_WARN, FIL__, __LINE__, status, MSG_E_SUBGEN,
742 _("sysctl()"),
743 _("getfiles"));
744 SH_MUTEX_UNLOCK(mutex_thread_nolog);
745 }
746 return ("-");
747 }
748 return (proc.ki_ocomm);
749}
750
751char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
752 char * user, size_t userlen)
753{
754 int n, hash;
755 struct xfile *xf;
756 struct in_addr * haddr;
757 struct sock * s;
758
759 for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
760
761 if (xf->xf_data == NULL)
762 continue;
763
764 /* Find the socket in sockhash[] that corresponds to it
765 */
766 hash = (int)((uintptr_t)xf->xf_data % HASHSIZE);
767 for (s = sockhash[hash]; s != NULL; s = s->next)
768 if ((void *)s->socket == xf->xf_data)
769 break;
770
771 if (!s)
772 continue;
773
774 /* fprintf(stderr, "FIXME: %d %d, %d %d, %d %d, %d, %d\n", s->proto, proto,
775 s->family, AF_INET,
776 sport, ntohs(((struct sockaddr_in *)(&s->laddr))->sin_port),
777 (int) xf->xf_uid, (int)xf->xf_pid);
778 */
779
780 if (s->proto != proto)
781 continue;
782
783 if (s->family != AF_INET /* && s->family != AF_INET6 */)
784 continue;
785
786 if (sport != ntohs(((struct sockaddr_in *)(&s->laddr))->sin_port))
787 continue;
788
789 haddr = &((struct sockaddr_in *)(&s->laddr))->sin_addr;
790
791 /* fprintf(stderr, "FIXME: %s\n", inet_ntoa(*haddr)); */
792 /* fprintf(stderr, "FIXME: %s\n", inet_ntoa(*saddr)); */
793
794 if (haddr->s_addr == saddr->s_addr || inet_lnaof(*saddr) == INADDR_ANY || inet_lnaof(*haddr) == INADDR_ANY)
795 {
796 struct sock_store try;
797
798 try.pid = xf->xf_pid;
799 try.path = NULL;
800 try.user = NULL;
801 get_user_and_path (&try); /* Try to get info from /proc */
802
803 if (try.path == NULL)
804 {
805 extern char * sh_unix_getUIDname (int level, uid_t uid, char * out, size_t len);
806 char * tmp = sh_unix_getUIDname (SH_ERR_ALL, xf->xf_uid, user, userlen);
807 if (!tmp)
808 sl_snprintf (user, userlen, "%ld", (unsigned long) xf->xf_uid);
809 return sh_util_strdup(getprocname(xf->xf_pid));
810 }
811 else
812 {
813 sl_strlcpy(user, try.user, userlen);
814 SH_FREE(try.user);
815 return try.path;
816 }
817 }
818 }
819 sl_strlcpy(user, "-", userlen);
820 return sh_util_strdup("-");
821}
822
823static void sockdel(struct sock * sock)
824{
825 if (sock)
826 {
827 if (sock->next)
828 sockdel(sock->next);
829 SH_FREE(sock);
830 }
831 return;
832}
833
834int sh_port2proc_prepare()
835{
836 int i;
837
838 if (xfiles)
839 {
840 SH_FREE(xfiles);
841 xfiles = NULL;
842 }
843
844 for (i = 0; i < HASHSIZE; ++i)
845 {
846 sockdel(sockhash[i]);
847 sockhash[i] = NULL;
848 }
849
850 /* Inet connections
851 */
852 gather_inet(IPPROTO_TCP);
853 gather_inet(IPPROTO_UDP);
854 gather_inet(IPPROTO_DIVERT);
855
856 getfiles();
857
858 return 0;
859}
860
861#else /* !defined(__linux__) && !defined(__FreeBSD__) */
862
863char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
864 char * user, size_t userlen)
865{
866 (void) proto;
867 (void) saddr;
868 (void) sport;
869
870 sl_strlcpy(user, "-", userlen);
871 return sh_util_strdup("-");
872}
873
874int sh_port2proc_prepare()
875{
876 return 0;
877}
878
879#endif
880
881#endif /* defined(SH_USE_PORTCHECK) */
Note: See TracBrowser for help on using the repository browser.