2 ** kernel/bsd43.c Low level kernel access functions for 4.3BSD
4 ** This program is in the public domain and may be used freely by anyone
7 ** Last update: 17 March 1993
9 ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
22 #include <sys/types.h>
24 #include <sys/param.h>
25 #include <sys/ioctl.h>
26 #include <sys/socket.h>
28 #include <sys/socketvar.h>
37 #include <sys/vmmac.h>
52 #include <sys/dir.h> /* tmk */
53 #include <sys/user.h> /* tmk */
54 /*#include <sys/time.h>
56 #include <sys/vmmac.h>
58 /*#include <sys/dir.h>
65 /*#include <sys/user.h>
74 #include <net/route.h>
75 #include <netinet/in.h>
77 #include <netinet/in_systm.h>
78 #include <netinet/ip.h>
80 #include <netinet/in_pcb.h>
82 #include <netinet/tcp.h>
83 #include <netinet/ip_var.h>
84 #include <netinet/tcp_timer.h>
85 #include <netinet/tcp_var.h>
87 #include <arpa/inet.h>
93 extern void *calloc();
94 extern void *malloc();
111 static struct file *xfile;
114 static struct inpcb tcb;
120 ** Open the kernel memory device
122 if (!(kd = kvm_open(path_unix, path_kmem, NULL, O_RDONLY, NULL)))
123 ERROR("main: kvm_open");
126 ** Extract offsets to the needed variables in the kernel
128 if (kvm_nlist(kd, nl) != 0)
129 ERROR("main: kvm_nlist");
136 ** Get a piece of kernel memory with error handling.
137 ** Returns 1 if call succeeded, else 0 (zero).
139 static int getbuf(addr, buf, len, what)
145 if (kvm_read(kd, addr, buf, len) < 0)
148 syslog(LOG_ERR, "getbuf: kvm_read(%08x, %d) - %s : %m",
160 ** Traverse the inpcb list until a match is found.
161 ** Returns NULL if no match.
163 static struct socket *
164 getlist(pcbp, faddr, fport, laddr, lport)
166 struct in_addr *faddr;
168 struct in_addr *laddr;
177 head = pcbp->inp_prev;
180 if ( pcbp->inp_faddr.s_addr == faddr->s_addr &&
181 pcbp->inp_laddr.s_addr == laddr->s_addr &&
182 pcbp->inp_fport == fport &&
183 pcbp->inp_lport == lport )
184 return pcbp->inp_socket;
185 } while (pcbp->inp_next != head &&
186 getbuf((long) pcbp->inp_next,
188 sizeof(struct inpcb),
197 ** Return the user number for the connection owner
199 int k_getuid(faddr, fport, laddr, lport, uid)
200 struct in_addr *faddr;
202 struct in_addr *laddr;
210 struct socket *sockp;
213 /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
214 if (!getbuf(nl[N_NFILE].n_value, &nfile, sizeof(nfile), "nfile"))
217 if (!getbuf(nl[N_FILE].n_value, &addr, sizeof(addr), "&file"))
220 xfile = (struct file *) calloc(nfile, sizeof(struct file));
222 ERROR2("k_getuid: calloc(%d,%d)", nfile, sizeof(struct file));
224 if (!getbuf(addr, xfile, sizeof(struct file)*nfile, "file[]"))
227 /* -------------------- TCP PCB LIST -------------------- */
228 if (!getbuf(nl[N_TCB].n_value, &tcb, sizeof(tcb), "tcb"))
231 tcb.inp_prev = (struct inpcb *) nl[N_TCB].n_value;
232 sockp = getlist(&tcb, faddr, fport, laddr, lport);
237 /* -------------------- SCAN PROCESS TABLE ------------------- */
238 if (kvm_setproc(kd) < 0)
239 ERROR("k_getuid: kvm_setproc() failed");
241 while (pp = kvm_nextproc(kd))
246 if (pp->p_stat == SZOMB)
249 /* ------------------- GET U_AREA FOR PROCESS ----------------- */
250 if ((up = kvm_getu(kd, pp)) == NULL)
251 ERROR1("k_getuid: kvm_getu() failed for process %d", pp->p_pid);
253 /* ------------------- SCAN FILE TABLE ------------------------ */
254 for (i = up->u_lastfile; i >= 0; i--)
256 if (up->u_ofile[i] == 0)
259 offset = up->u_ofile[i] - (struct file *) addr;
260 if (xfile[offset].f_type == DTYPE_SOCKET &&
261 (struct socket *) xfile[offset].f_data == sockp)
270 } /* for -- ofiles */