1: /*
   2: ** kernel/2.11bsd.c		Low level kernel access functions for 2.11BSD
   3: **
   4: ** This program is in the public domain and may be used freely by anyone
   5: ** who wants to.
   6: **
   7: ** Last update: 05 December 1999
   8: **
   9: ** Please send bug fixes/bug reports to: Steven Schultz <sms@moe.2bsd.com>
  10: */
  11: 
  12: #include <stdio.h>
  13: #include <nlist.h>
  14: #include <syslog.h>
  15: #include <unistd.h>
  16: 
  17: #include "kvm.h"
  18: 
  19: #include <sys/types.h>
  20: #include <sys/param.h>
  21: #include <sys/socket.h>
  22: #include <sys/socketvar.h>
  23: 
  24: #define KERNEL
  25: #include <sys/file.h>
  26: #undef  KERNEL
  27: #include <sys/dir.h>
  28: #include <sys/user.h>
  29: #include <sys/proc.h>
  30: #include <fcntl.h>
  31: #include <sys/sysctl.h>
  32: 
  33: #include <netinet/in.h>
  34: 
  35: #include <netinet/in_systm.h>
  36: #include <netinet/ip.h>
  37: #include <net/route.h>
  38: #include <netinet/in_pcb.h>
  39: 
  40: #include "identd.h"
  41: #include "error.h"
  42: 
  43:     struct nlist nl[] =
  44:         {
  45: #define N_NETDATA 0
  46:         { "_netdata" },
  47:         { "" }
  48:         };
  49: 
  50:     struct  nlist   snl[] =
  51:         {
  52: #define SN_TCB  0
  53:         { "_tcb" },
  54:         { "" }
  55:         };
  56: 
  57:     static  off_t   netoff;
  58:     static struct inpcb tcb;
  59:     static  int memfd, swapfd;
  60: 
  61: #ifndef _PATH_MEM
  62: #define _PATH_MEM   "/dev/mem"
  63: #endif
  64: 
  65: #ifndef _PATH_SWAP
  66: #define _PATH_SWAP  "/dev/swap"
  67: #endif
  68: 
  69: #ifndef _PATH_UNIX
  70: #define _PATH_UNIX  "/unix"
  71: #endif
  72: 
  73: #ifndef _PATH_NETNIX
  74: #define _PATH_NETNIX    "/netnix"
  75: #endif
  76: 
  77:     static  char    Msg_open[] = "open %s";
  78:     static  char    Msg_nlist[] = "nlist %s";
  79:     static  char    Msg_sysctl[] = "sysctl %s";
  80:     static  char    Msg_readu[] = "can't read u pid %d";
  81:     static  char    Msg_malloc[] = "malloc(%d)";
  82:     static  char    Swap[] = _PATH_SWAP;
  83:     static  char    Netnix[] = _PATH_NETNIX;
  84: 
  85:     static  struct  file    *sockp2fp();
  86:     static  void    error(), error1();
  87: 
  88: int
  89: k_open()
  90:     {
  91:     u_int   netdata;
  92:     char    *p;
  93: 
  94:     if  (path_kmem)
  95:         p = path_kmem;
  96:     else
  97:         p = _PATH_MEM;
  98:     memfd = open(p, O_RDONLY);
  99:     if  (memfd < 0)
 100:             error1(Msg_open, p);
 101: 
 102:     swapfd = open(Swap, O_RDONLY);
 103:     if  (swapfd < 0)
 104:         error1(Msg_open, Swap);
 105: 
 106:     if  (path_unix)
 107:         p = path_unix;
 108:     else
 109:         p = _PATH_UNIX;
 110:     if  (nlist(p, nl) != 0)
 111:             error1(Msg_nlist, p);
 112: 
 113:     if  (nlist(Netnix, snl) != 0)
 114:         error1(Msg_nlist, Netnix);
 115:     if  (getbuf((off_t)nl[N_NETDATA].n_value, &netdata, sizeof (int),
 116:             "netdata") == 0)
 117:         exit(1);
 118: 
 119:     netoff = (off_t)ctob((long)netdata);
 120:     return(0);
 121:     }
 122: 
 123: /*
 124:  * Get a piece of kernel memory with error handling.
 125:  * Returns 1 if call succeeded, else 0 (zero).
 126: */
 127: static int
 128: getbuf(addr, buf, len, what)
 129:     off_t addr;
 130:     char *buf;
 131:     int len;
 132:     char *what;
 133:     {
 134: 
 135:     if  (lseek(memfd, addr, L_SET) == -1)
 136:         {
 137:         if  (syslog_flag)
 138:             syslog(LOG_ERR, "getbuf: lseek %ld - %s: %m",what,addr);
 139:         return(0);
 140:         }
 141:     if  (read(memfd, buf, len) != len)
 142:         {
 143:         if  (syslog_flag)
 144:             syslog(LOG_ERR, "getbuf: read %d bytes - %s : %m",
 145:                 len, what);
 146:         return(0);
 147:         }
 148:     return(1);
 149:     }
 150: 
 151: /*
 152:  * Traverse the inpcb list until a match is found.
 153:  * Returns NULL if no match.
 154: */
 155: static struct socket *
 156: getlist(pcbp, faddr, fport, laddr, lport)
 157:     register struct inpcb *pcbp;
 158:     register struct in_addr *faddr;
 159:     int fport;
 160:     register struct in_addr *laddr;
 161:     int lport;
 162:     {
 163:     struct inpcb *head;
 164: 
 165:     if  (!pcbp)
 166:         return(NULL);
 167:     head = pcbp->inp_prev;
 168:     do
 169:         {
 170:         if  (pcbp->inp_faddr.s_addr == faddr->s_addr &&
 171:              pcbp->inp_laddr.s_addr == laddr->s_addr &&
 172:              pcbp->inp_fport        == fport &&
 173:              pcbp->inp_lport        == lport )
 174:             return(pcbp->inp_socket);
 175:         } while (pcbp->inp_next != head &&
 176:             getbuf((off_t)pcbp->inp_next + netoff,
 177:                 pcbp, sizeof(struct inpcb), "tcblist"));
 178:     return(NULL);
 179:     }
 180: 
 181: /*
 182:  * Return the user number for the connection owner
 183: */
 184: int
 185: k_getuid(faddr, fport, laddr, lport, uid)
 186:     struct  in_addr *faddr;
 187:     u_short fport;
 188:     struct  in_addr *laddr;
 189:     u_short lport;
 190:     uid_t   *uid;
 191:     {
 192:     register struct proc    *pp;
 193:     register struct user    *up;
 194:     struct  file    *fp;
 195:     struct  kinfo_proc *kpp, *xproc, *endproc;
 196:     struct  kinfo_file *xfile, *endfile;
 197:     struct socket *sockp;
 198:     register int i;
 199:     int mib[3], size;
 200:     struct  user    uarea;
 201: 
 202:   /* -------------------- FILE DESCRIPTOR TABLE -------------------- */
 203: 
 204:     mib[0] = CTL_KERN;
 205:     mib[1] = KERN_FILE;
 206:     i = sysctl(mib, 2, NULL, &size, NULL, 0);
 207:     if  (i == -1)
 208:         error1(Msg_sysctl, "1");
 209:     xfile = (struct kinfo_file *) malloc(size);
 210:     if  (!xfile)
 211:             error1(Msg_malloc, size);
 212:     i = sysctl(mib, 2, xfile, &size, NULL, 0);
 213:     if  (i == -1)
 214:         error1(Msg_sysctl, "2");
 215:     endfile = &xfile[size / sizeof (struct kinfo_file)];
 216: 
 217:   /* -------------------- TCP PCB LIST -------------------- */
 218:     if  (!getbuf((off_t)snl[SN_TCB].n_value + netoff, &tcb,
 219:             sizeof(tcb), "tcb"))
 220:         {
 221:         free(xfile);
 222:         return(-1);
 223:         }
 224:     tcb.inp_prev = (struct inpcb *) snl[SN_TCB].n_value;
 225:     sockp = getlist(&tcb, faddr, fport, laddr, lport);
 226:     if  (!sockp)
 227:         {
 228:         free(xfile);
 229:         return(-1);
 230:         }
 231:   /* ------------------- FIND FILE CONTAINING TCP CONTROL BLOCK --------- */
 232:     fp = sockp2fp(xfile, endfile, sockp);
 233:     if  (!fp)
 234:         {
 235:         free(xfile);
 236:         return(-1);
 237:         }
 238: 
 239:   /* -------------------- PROCESS TABLE ------------------- */
 240:     mib[0] = CTL_KERN;
 241:     mib[1] = KERN_PROC;
 242:     mib[2] = KERN_PROC_ALL;
 243:     i = sysctl(mib, 3, NULL, &size, NULL, 0);
 244:     if  (i == -1)
 245:         error1(Msg_sysctl, "3");
 246:     xproc = (struct kinfo_proc *)malloc(size);
 247:     if  (!xproc)
 248:             error1(Msg_malloc, size);
 249:     i = sysctl(mib, 3, xproc, &size, NULL, 0);
 250:     if  (i == -1)
 251:         error1(Msg_sysctl, "4");
 252:     endproc = &xproc[size / sizeof (struct kinfo_proc)];
 253: 
 254:     for (kpp = xproc; kpp < endproc; kpp++)
 255:         {
 256:         pp = &kpp->kp_proc;
 257:         if  (pp->p_stat == SZOMB)
 258:             continue;
 259: 
 260:     /* ------------------- GET U_AREA FOR PROCESS ----------------- */
 261:         if  (pp->p_flag & SLOAD)
 262:             {
 263:             if  (getbuf(ctob((off_t)pp->p_addr),&uarea,
 264:                     sizeof (uarea), "u") == 0)
 265:                 error1(Msg_readu, pp->p_pid);
 266:             }
 267:         else
 268:             {
 269:             lseek(swapfd, dbtob((off_t)pp->p_addr), L_SET);
 270:             i = read(swapfd, &uarea, sizeof (uarea));
 271:             if  (i != sizeof (uarea))
 272:                 error1(Msg_readu, pp->p_pid);
 273:             }
 274:         up = &uarea;
 275: 
 276:     /* ----------------- SCAN PROCESS's FILE TABLE ------------------- */
 277:         for (i = up->u_lastfile; i >= 0; i--)
 278:             {
 279:             if  (up->u_ofile[i] == fp)
 280:                 {
 281:                 *uid = up->u_ruid;
 282:                 free(xproc);
 283:                 free(xfile);
 284:                 return(0);
 285:                 }       /* if */
 286:             }           /* for -- ofiles */
 287:         }                   /* for -- proc */
 288:     free(xproc);
 289:     free(xfile);
 290:     return -1;
 291:     }
 292: 
 293: static struct file *
 294: sockp2fp(xfile, endfile, sockp)
 295:     struct  kinfo_file *xfile, *endfile;
 296:     struct  socket  *sockp;
 297:     {
 298:     register struct kinfo_file *kfp;
 299:     register struct file *fp = NULL;
 300: 
 301:     for (kfp = xfile; kfp < endfile; kfp++)
 302:         {
 303:         if  ((kfp->kp_file.f_type == DTYPE_SOCKET) &&
 304:              (kfp->kp_file.f_data == sockp))
 305:             {
 306:             fp = kfp->kp_filep;
 307:             break;
 308:             }
 309:         }
 310:     return(fp);
 311:     }
 312: 
 313: /*
 314:  * These are helper functions which greatly reduce the bloat caused by
 315:  * inline expansion of the ERROR and ERROR1 macros (this module went from
 316:  * about 2700 bytes of code to 1400 bytes!).  Those macros _should_
 317:  * have been written as variadic functions using vfprintf and vsyslog!
 318:  *
 319:  * error1() only accepts single word (int, not long) as a second arg.
 320: */
 321: 
 322: static void
 323: error(msg)
 324:     char    *msg;
 325:     {
 326:     ERROR(msg);
 327:     /* NOTREACHED */
 328:     }
 329: 
 330: /* ARGSUSED1 */
 331: static void
 332: error1(msg, arg2)
 333:     char    *msg;
 334:     int arg2;
 335:     {
 336:     ERROR1(msg, arg2);
 337:     /* NOTREACHED */
 338:     }

Defined functions

error defined in line 322; used 1 times
  • in line 86
error1 defined in line 331; used 13 times
getbuf defined in line 127; used 4 times
getlist defined in line 155; used 1 times
k_getuid defined in line 184; never used
k_open defined in line 88; never used
sockp2fp defined in line 293; used 2 times

Defined variables

Msg_malloc defined in line 81; used 2 times
Msg_nlist defined in line 78; used 2 times
Msg_open defined in line 77; used 2 times
Msg_readu defined in line 80; used 2 times
Msg_sysctl defined in line 79; used 4 times
Netnix defined in line 83; used 2 times
Swap defined in line 82; used 2 times
memfd defined in line 59; used 4 times
netoff defined in line 57; used 3 times
nl defined in line 43; used 2 times
snl defined in line 50; used 3 times
swapfd defined in line 59; used 4 times
tcb defined in line 58; used 4 times

Defined macros

KERNEL defined in line 24; used 1 times
  • in line 26
N_NETDATA defined in line 45; used 1 times
SN_TCB defined in line 52; used 2 times
_PATH_MEM defined in line 62; used 2 times
_PATH_NETNIX defined in line 74; used 2 times
_PATH_SWAP defined in line 66; used 2 times
_PATH_UNIX defined in line 70; used 2 times
Last modified: 1996-12-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5087
Valid CSS Valid XHTML 1.0 Strict