freebsd5 proc_port impl
This commit is contained in:
		
							parent
							
								
									2582ada2b9
								
							
						
					
					
						commit
						d4eb411774
					
				@ -1536,6 +1536,123 @@ int sigar_net_connection_list_get(sigar_t *sigar,
 | 
			
		||||
    return SIGAR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define _KERNEL
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#undef _KERNEL
 | 
			
		||||
 | 
			
		||||
/* derived from
 | 
			
		||||
 * /usr/ports/security/pidentd/work/pidentd-3.0.16/src/k_freebsd2.c
 | 
			
		||||
 */
 | 
			
		||||
int sigar_proc_port_get(sigar_t *sigar, int protocol,
 | 
			
		||||
                        unsigned long port, sigar_pid_t *pid)
 | 
			
		||||
{
 | 
			
		||||
    struct nlist nl[2];
 | 
			
		||||
    struct inpcbhead tcb;
 | 
			
		||||
    struct socket *sockp = NULL;
 | 
			
		||||
    struct kinfo_proc *pinfo;
 | 
			
		||||
    struct inpcb *head, pcbp;
 | 
			
		||||
    int i, nentries, status;
 | 
			
		||||
 | 
			
		||||
    if (protocol != SIGAR_NETCONN_TCP) {
 | 
			
		||||
        return SIGAR_ENOTIMPL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!sigar->kmem) {
 | 
			
		||||
        return EPERM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nl[0].n_name = "_tcb"; /* XXX cache */
 | 
			
		||||
    if (kvm_nlist(sigar->kmem, nl) < 0) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    status = kread(sigar, &tcb, sizeof(tcb), nl[0].n_value);
 | 
			
		||||
    if (status != SIGAR_OK) {
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (head = tcb.lh_first; head != NULL;
 | 
			
		||||
         head = pcbp.inp_list.le_next)
 | 
			
		||||
    {
 | 
			
		||||
        status = kread(sigar, &pcbp, sizeof(pcbp), (long)head);
 | 
			
		||||
        if (status != SIGAR_OK) {
 | 
			
		||||
            return status;
 | 
			
		||||
        }
 | 
			
		||||
        if (!(pcbp.inp_vflag & INP_IPV4)) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (pcbp.inp_fport != 0) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (ntohs(pcbp.inp_lport) == port) {
 | 
			
		||||
            sockp = pcbp.inp_socket;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!sockp) {
 | 
			
		||||
        return ENOENT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pinfo = kvm_getprocs(sigar->kmem, KERN_PROC_ALL, 0, &nentries);
 | 
			
		||||
    if (!pinfo) {
 | 
			
		||||
        return errno;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<nentries; i++) {
 | 
			
		||||
        if (pinfo[i].ki_fd) {
 | 
			
		||||
            struct filedesc pfd;
 | 
			
		||||
            struct file **ofiles, ofile;
 | 
			
		||||
            int j, osize;
 | 
			
		||||
 | 
			
		||||
            status = kread(sigar, &pfd, sizeof(pfd), (long)pinfo[i].ki_fd);
 | 
			
		||||
            if (status != SIGAR_OK) {
 | 
			
		||||
                return status;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            osize = pfd.fd_nfiles * sizeof(struct file *);
 | 
			
		||||
            ofiles = malloc(osize); /* XXX reuse */
 | 
			
		||||
            if (!ofiles) {
 | 
			
		||||
                return errno;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            status = kread(sigar, ofiles, osize, (long)pfd.fd_ofiles);
 | 
			
		||||
            if (status != SIGAR_OK) {
 | 
			
		||||
                free(ofiles);
 | 
			
		||||
                return status;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (j=0; j<pfd.fd_nfiles; j++) {
 | 
			
		||||
                if (!ofiles[j]) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                status = kread(sigar, &ofile, sizeof(ofile), (long)ofiles[j]);
 | 
			
		||||
                if (status != SIGAR_OK) {
 | 
			
		||||
                    free(ofiles);
 | 
			
		||||
                    return status;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (ofile.f_count == 0) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (ofile.f_type == DTYPE_SOCKET &&
 | 
			
		||||
                    (struct socket *)ofile.f_data == sockp)
 | 
			
		||||
                {
 | 
			
		||||
                    *pid = pinfo[i].ki_pid;
 | 
			
		||||
                    free(ofiles);
 | 
			
		||||
                    return SIGAR_OK;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            free(ofiles);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ENOENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
int sigar_net_connection_list_get(sigar_t *sigar,
 | 
			
		||||
@ -1545,10 +1662,10 @@ int sigar_net_connection_list_get(sigar_t *sigar,
 | 
			
		||||
    return SIGAR_ENOTIMPL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int sigar_proc_port_get(sigar_t *sigar, int protocol,
 | 
			
		||||
                        unsigned long port, sigar_pid_t *pid)
 | 
			
		||||
{
 | 
			
		||||
    return SIGAR_ENOTIMPL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user