# 2.11BSD#431 - /usr/src/libexec/identd/src/kernel/2.11bsd.c

##### Functions

    k_getuid          X
    k_open            X

##### Variables

    nl                X
    snl               X

##### Macros

    KERNEL            X
    N_NETDATA         X
    SN_TCB            X
    _PATH_MEM         X
    _PATH_NETNIX      X
    _PATH_SWAP        X
    _PATH_UNIX        X

       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

- in line 86, 100-104(2), 111-114(2), 208-214(3), 245-251(3), 265, 272

getbuf defined in line 127; used 4 times

- in line 115, 176, 218, 263

getlist defined in line 155; used 1 times

- in line 225

k_getuid defined in line 184; never used
k_open defined in line 88; never used
sockp2fp defined in line 293; used 2 times

- in line 85, 232

#### Defined variables

Msg_malloc defined in line 81; used 2 times

- in line 211, 248

Msg_nlist defined in line 78; used 2 times

- in line 111-114(2)

Msg_open defined in line 77; used 2 times

- in line 100-104(2)

Msg_readu defined in line 80; used 2 times

- in line 265, 272

Msg_sysctl defined in line 79; used 4 times

- in line 208, 214, 245, 251

Netnix defined in line 83; used 2 times

- in line 113-114(2)

Swap defined in line 82; used 2 times

- in line 102-104(2)

memfd defined in line 59; used 4 times

- in line 98-99(2), 135, 141

netoff defined in line 57; used 3 times

- in line 119, 176, 218

nl defined in line 43; used 2 times

- in line 110-115(2)

snl defined in line 50; used 3 times

- in line 113, 218, 224

swapfd defined in line 59; used 4 times

- in line 102-103(2), 269-270(2)

tcb defined in line 58; used 4 times

- in line 218-225(4)

#### Defined macros

KERNEL defined in line 24; used 1 times

- in line 26

N_NETDATA defined in line 45; used 1 times

- in line 115

SN_TCB defined in line 52; used 2 times

- in line 218, 224

_PATH_MEM defined in line 62; used 2 times

- in line 61, 97

_PATH_NETNIX defined in line 74; used 2 times

- in line 73, 83

_PATH_SWAP defined in line 66; used 2 times

- in line 65, 82

_PATH_UNIX defined in line 70; used 2 times

- in line 69, 109

Last modified: 1996-12-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2402 |