Print this page
XXXX adding PID information to netstat output


  60 #include <sys/debug.h>
  61 #include <sys/strredir.h>
  62 #include <sys/fs/fifonode.h>
  63 #include <sys/fs/snode.h>
  64 #include <sys/strlog.h>
  65 #include <sys/strsun.h>
  66 #include <sys/project.h>
  67 #include <sys/kbio.h>
  68 #include <sys/msio.h>
  69 #include <sys/tty.h>
  70 #include <sys/ptyvar.h>
  71 #include <sys/vuid_event.h>
  72 #include <sys/modctl.h>
  73 #include <sys/sunddi.h>
  74 #include <sys/sunldi_impl.h>
  75 #include <sys/autoconf.h>
  76 #include <sys/policy.h>
  77 #include <sys/dld.h>
  78 #include <sys/zone.h>
  79 #include <c2/audit.h>

  80 
  81 /*
  82  * This define helps improve the readability of streams code while
  83  * still maintaining a very old streams performance enhancement.  The
  84  * performance enhancement basically involved having all callers
  85  * of straccess() perform the first check that straccess() will do
  86  * locally before actually calling straccess().  (There by reducing
  87  * the number of unnecessary calls to straccess().)
  88  */
  89 #define i_straccess(x, y)       ((stp->sd_sidp == NULL) ? 0 : \
  90                                     (stp->sd_vnode->v_type == VFIFO) ? 0 : \
  91                                     straccess((x), (y)))
  92 
  93 /*
  94  * what is mblk_pull_len?
  95  *
  96  * If a streams message consists of many short messages,
  97  * a performance degradation occurs from copyout overhead.
  98  * To decrease the per mblk overhead, messages that are
  99  * likely to consist of many small mblks are pulled up into


 125  * The "new semantics" are that TIOCGETP returns B38400 for
 126  * sg_[io]speed if the corresponding value is over B38400, and that
 127  * TIOCSET[PN] accept B38400 in these cases to mean "retain current
 128  * bit rate."
 129  */
 130 int sgttyb_handling = 1;
 131 static boolean_t sgttyb_complaint;
 132 
 133 /* don't push drcompat module by default on Style-2 streams */
 134 static int push_drcompat = 0;
 135 
 136 /*
 137  * id value used to distinguish between different ioctl messages
 138  */
 139 static uint32_t ioc_id;
 140 
 141 static void putback(struct stdata *, queue_t *, mblk_t *, int);
 142 static void strcleanall(struct vnode *);
 143 static int strwsrv(queue_t *);
 144 static int strdocmd(struct stdata *, struct strcmd *, cred_t *);

 145 
 146 /*
 147  * qinit and module_info structures for stream head read and write queues
 148  */
 149 struct module_info strm_info = { 0, "strrhead", 0, INFPSZ, STRHIGH, STRLOW };
 150 struct module_info stwm_info = { 0, "strwhead", 0, 0, 0, 0 };
 151 struct qinit strdata = { strrput, NULL, NULL, NULL, NULL, &strm_info };
 152 struct qinit stwdata = { NULL, strwsrv, NULL, NULL, NULL, &stwm_info };
 153 struct module_info fiform_info = { 0, "fifostrrhead", 0, PIPE_BUF, FIFOHIWAT,
 154     FIFOLOWAT };
 155 struct module_info fifowm_info = { 0, "fifostrwhead", 0, 0, 0, 0 };
 156 struct qinit fifo_strdata = { strrput, NULL, NULL, NULL, NULL, &fiform_info };
 157 struct qinit fifo_stwdata = { NULL, strwsrv, NULL, NULL, NULL, &fifowm_info };
 158 
 159 extern kmutex_t strresources;   /* protects global resources */
 160 extern kmutex_t muxifier;       /* single-threads multiplexor creation */
 161 
 162 static boolean_t msghasdata(mblk_t *bp);
 163 #define msgnodata(bp) (!msghasdata(bp))
 164 


 379         stp->sd_sigflags = 0;
 380         stp->sd_mark = NULL;
 381         stp->sd_closetime = STRTIMOUT;
 382         stp->sd_sidp = NULL;
 383         stp->sd_pgidp = NULL;
 384         stp->sd_vnode = vp;
 385         stp->sd_rerror = 0;
 386         stp->sd_werror = 0;
 387         stp->sd_wroff = 0;
 388         stp->sd_tail = 0;
 389         stp->sd_iocblk = NULL;
 390         stp->sd_cmdblk = NULL;
 391         stp->sd_pushcnt = 0;
 392         stp->sd_qn_minpsz = 0;
 393         stp->sd_qn_maxpsz = INFPSZ - 1;      /* used to check for initialization */
 394         stp->sd_maxblk = INFPSZ;
 395         qp->q_ptr = _WR(qp)->q_ptr = stp;
 396         STREAM(qp) = STREAM(_WR(qp)) = stp;
 397         vp->v_stream = stp;
 398         mutex_exit(&vp->v_lock);








 399         if (vp->v_type == VFIFO) {
 400                 stp->sd_flag |= OLDNDELAY;
 401                 /*
 402                  * This means, both for pipes and fifos
 403                  * strwrite will send SIGPIPE if the other
 404                  * end is closed. For putmsg it depends
 405                  * on whether it is a XPG4_2 application
 406                  * or not
 407                  */
 408                 stp->sd_wput_opt = SW_SIGPIPE;
 409 
 410                 /* setq might sleep in kmem_alloc - avoid holding locks. */
 411                 setq(qp, &fifo_strdata, &fifo_stwdata, NULL, QMTSAFE,
 412                     SQ_CI|SQ_CO, B_FALSE);
 413 
 414                 set_qend(qp);
 415                 stp->sd_strtab = fifo_getinfo();
 416                 _WR(qp)->q_nfsrv = _WR(qp);
 417                 qp->q_nfsrv = qp;
 418                 /*


5665                 return (strcopyout(&pgrp, (void *)arg, sizeof (pid_t),
5666                     copyflag));
5667         }
5668 
5669         case TIOCSCTTY:
5670         {
5671                 return (strctty(stp));
5672         }
5673 
5674         case TIOCNOTTY:
5675         {
5676                 /* freectty() always assumes curproc. */
5677                 if (freectty(B_FALSE) != 0)
5678                         return (0);
5679                 return (ENOTTY);
5680         }
5681 
5682         case FIONBIO:
5683         case FIOASYNC:
5684                 return (0);     /* handled by the upper layer */
















5685         }
5686 }
5687 
5688 /*
5689  * Custom free routine used for M_PASSFP messages.
5690  */
5691 static void
5692 free_passfp(struct k_strrecvfd *srf)
5693 {
5694         (void) closef(srf->fp);
5695         kmem_free(srf, sizeof (struct k_strrecvfd) + sizeof (frtn_t));
5696 }
5697 
5698 /* ARGSUSED */
5699 int
5700 do_sendfp(struct stdata *stp, struct file *fp, struct cred *cr)
5701 {
5702         queue_t *qp, *nextqp;
5703         struct k_strrecvfd *srf;
5704         mblk_t *mp;


8595         if (update) {
8596                 stp->sd_sigflags = 0;
8597                 for (ssp = stp->sd_siglist; ssp; ssp = ssp->ss_next)
8598                         stp->sd_sigflags |= ssp->ss_events;
8599         }
8600         mutex_exit(&stp->sd_lock);
8601 }
8602 
8603 /*
8604  * Return B_TRUE if there is data in the message, B_FALSE otherwise.
8605  */
8606 static boolean_t
8607 msghasdata(mblk_t *bp)
8608 {
8609         for (; bp; bp = bp->b_cont)
8610                 if (bp->b_datap->db_type == M_DATA) {
8611                         ASSERT(bp->b_wptr >= bp->b_rptr);
8612                         if (bp->b_wptr > bp->b_rptr)
8613                                 return (B_TRUE);
8614                 }






























8615         return (B_FALSE);
8616 }


  60 #include <sys/debug.h>
  61 #include <sys/strredir.h>
  62 #include <sys/fs/fifonode.h>
  63 #include <sys/fs/snode.h>
  64 #include <sys/strlog.h>
  65 #include <sys/strsun.h>
  66 #include <sys/project.h>
  67 #include <sys/kbio.h>
  68 #include <sys/msio.h>
  69 #include <sys/tty.h>
  70 #include <sys/ptyvar.h>
  71 #include <sys/vuid_event.h>
  72 #include <sys/modctl.h>
  73 #include <sys/sunddi.h>
  74 #include <sys/sunldi_impl.h>
  75 #include <sys/autoconf.h>
  76 #include <sys/policy.h>
  77 #include <sys/dld.h>
  78 #include <sys/zone.h>
  79 #include <c2/audit.h>
  80 #include <sys/fcntl.h>
  81 
  82 /*
  83  * This define helps improve the readability of streams code while
  84  * still maintaining a very old streams performance enhancement.  The
  85  * performance enhancement basically involved having all callers
  86  * of straccess() perform the first check that straccess() will do
  87  * locally before actually calling straccess().  (There by reducing
  88  * the number of unnecessary calls to straccess().)
  89  */
  90 #define i_straccess(x, y)       ((stp->sd_sidp == NULL) ? 0 : \
  91                                     (stp->sd_vnode->v_type == VFIFO) ? 0 : \
  92                                     straccess((x), (y)))
  93 
  94 /*
  95  * what is mblk_pull_len?
  96  *
  97  * If a streams message consists of many short messages,
  98  * a performance degradation occurs from copyout overhead.
  99  * To decrease the per mblk overhead, messages that are
 100  * likely to consist of many small mblks are pulled up into


 126  * The "new semantics" are that TIOCGETP returns B38400 for
 127  * sg_[io]speed if the corresponding value is over B38400, and that
 128  * TIOCSET[PN] accept B38400 in these cases to mean "retain current
 129  * bit rate."
 130  */
 131 int sgttyb_handling = 1;
 132 static boolean_t sgttyb_complaint;
 133 
 134 /* don't push drcompat module by default on Style-2 streams */
 135 static int push_drcompat = 0;
 136 
 137 /*
 138  * id value used to distinguish between different ioctl messages
 139  */
 140 static uint32_t ioc_id;
 141 
 142 static void putback(struct stdata *, queue_t *, mblk_t *, int);
 143 static void strcleanall(struct vnode *);
 144 static int strwsrv(queue_t *);
 145 static int strdocmd(struct stdata *, struct strcmd *, cred_t *);
 146 static boolean_t is_xti_str(const struct stdata *);
 147 
 148 /*
 149  * qinit and module_info structures for stream head read and write queues
 150  */
 151 struct module_info strm_info = { 0, "strrhead", 0, INFPSZ, STRHIGH, STRLOW };
 152 struct module_info stwm_info = { 0, "strwhead", 0, 0, 0, 0 };
 153 struct qinit strdata = { strrput, NULL, NULL, NULL, NULL, &strm_info };
 154 struct qinit stwdata = { NULL, strwsrv, NULL, NULL, NULL, &stwm_info };
 155 struct module_info fiform_info = { 0, "fifostrrhead", 0, PIPE_BUF, FIFOHIWAT,
 156     FIFOLOWAT };
 157 struct module_info fifowm_info = { 0, "fifostrwhead", 0, 0, 0, 0 };
 158 struct qinit fifo_strdata = { strrput, NULL, NULL, NULL, NULL, &fiform_info };
 159 struct qinit fifo_stwdata = { NULL, strwsrv, NULL, NULL, NULL, &fifowm_info };
 160 
 161 extern kmutex_t strresources;   /* protects global resources */
 162 extern kmutex_t muxifier;       /* single-threads multiplexor creation */
 163 
 164 static boolean_t msghasdata(mblk_t *bp);
 165 #define msgnodata(bp) (!msghasdata(bp))
 166 


 381         stp->sd_sigflags = 0;
 382         stp->sd_mark = NULL;
 383         stp->sd_closetime = STRTIMOUT;
 384         stp->sd_sidp = NULL;
 385         stp->sd_pgidp = NULL;
 386         stp->sd_vnode = vp;
 387         stp->sd_rerror = 0;
 388         stp->sd_werror = 0;
 389         stp->sd_wroff = 0;
 390         stp->sd_tail = 0;
 391         stp->sd_iocblk = NULL;
 392         stp->sd_cmdblk = NULL;
 393         stp->sd_pushcnt = 0;
 394         stp->sd_qn_minpsz = 0;
 395         stp->sd_qn_maxpsz = INFPSZ - 1;      /* used to check for initialization */
 396         stp->sd_maxblk = INFPSZ;
 397         qp->q_ptr = _WR(qp)->q_ptr = stp;
 398         STREAM(qp) = STREAM(_WR(qp)) = stp;
 399         vp->v_stream = stp;
 400         mutex_exit(&vp->v_lock);
 401 
 402         /*
 403          * If this is not a system process, then add it to
 404          * the list associated with the stream head.
 405          */
 406         if (!(curproc->p_flag & SSYS) && is_xti_str(stp))
 407                 sh_insert_pid(stp, curproc->p_pidp->pid_id);
 408 
 409         if (vp->v_type == VFIFO) {
 410                 stp->sd_flag |= OLDNDELAY;
 411                 /*
 412                  * This means, both for pipes and fifos
 413                  * strwrite will send SIGPIPE if the other
 414                  * end is closed. For putmsg it depends
 415                  * on whether it is a XPG4_2 application
 416                  * or not
 417                  */
 418                 stp->sd_wput_opt = SW_SIGPIPE;
 419 
 420                 /* setq might sleep in kmem_alloc - avoid holding locks. */
 421                 setq(qp, &fifo_strdata, &fifo_stwdata, NULL, QMTSAFE,
 422                     SQ_CI|SQ_CO, B_FALSE);
 423 
 424                 set_qend(qp);
 425                 stp->sd_strtab = fifo_getinfo();
 426                 _WR(qp)->q_nfsrv = _WR(qp);
 427                 qp->q_nfsrv = qp;
 428                 /*


5675                 return (strcopyout(&pgrp, (void *)arg, sizeof (pid_t),
5676                     copyflag));
5677         }
5678 
5679         case TIOCSCTTY:
5680         {
5681                 return (strctty(stp));
5682         }
5683 
5684         case TIOCNOTTY:
5685         {
5686                 /* freectty() always assumes curproc. */
5687                 if (freectty(B_FALSE) != 0)
5688                         return (0);
5689                 return (ENOTTY);
5690         }
5691 
5692         case FIONBIO:
5693         case FIOASYNC:
5694                 return (0);     /* handled by the upper layer */
5695         case F_ASSOCI_PID:
5696         {
5697                 if (crp != kcred)
5698                         return (EPERM);
5699                 if (is_xti_str(stp))
5700                         sh_insert_pid(stp, (pid_t)arg);
5701                 return (0);
5702         }
5703         case F_DASSOC_PID:
5704         {
5705                 if (crp != kcred)
5706                         return (EPERM);
5707                 if (is_xti_str(stp))
5708                         sh_remove_pid(stp, (pid_t)arg);
5709                 return (0);
5710         }
5711         }
5712 }
5713 
5714 /*
5715  * Custom free routine used for M_PASSFP messages.
5716  */
5717 static void
5718 free_passfp(struct k_strrecvfd *srf)
5719 {
5720         (void) closef(srf->fp);
5721         kmem_free(srf, sizeof (struct k_strrecvfd) + sizeof (frtn_t));
5722 }
5723 
5724 /* ARGSUSED */
5725 int
5726 do_sendfp(struct stdata *stp, struct file *fp, struct cred *cr)
5727 {
5728         queue_t *qp, *nextqp;
5729         struct k_strrecvfd *srf;
5730         mblk_t *mp;


8621         if (update) {
8622                 stp->sd_sigflags = 0;
8623                 for (ssp = stp->sd_siglist; ssp; ssp = ssp->ss_next)
8624                         stp->sd_sigflags |= ssp->ss_events;
8625         }
8626         mutex_exit(&stp->sd_lock);
8627 }
8628 
8629 /*
8630  * Return B_TRUE if there is data in the message, B_FALSE otherwise.
8631  */
8632 static boolean_t
8633 msghasdata(mblk_t *bp)
8634 {
8635         for (; bp; bp = bp->b_cont)
8636                 if (bp->b_datap->db_type == M_DATA) {
8637                         ASSERT(bp->b_wptr >= bp->b_rptr);
8638                         if (bp->b_wptr > bp->b_rptr)
8639                                 return (B_TRUE);
8640                 }
8641         return (B_FALSE);
8642 }
8643 
8644 /*
8645  * Check whether a stream is an XTI stream or not.
8646  */
8647 static boolean_t
8648 is_xti_str(const struct stdata *stp)
8649 {
8650         struct devnames *dnp;
8651         vnode_t *vn;
8652         major_t major;
8653         if ((vn = stp->sd_vnode) != NULL && vn->v_type == VCHR &&
8654             vn->v_rdev != 0) {
8655                 major = getmajor(vn->v_rdev);
8656                 dnp = (major != DDI_MAJOR_T_NONE && major >= 0 &&
8657                     major < devcnt) ? &devnamesp[major] : NULL;
8658                 if (dnp != NULL && dnp->dn_name != NULL &&
8659                     (strcmp(dnp->dn_name, "ip") == 0 ||
8660                     strcmp(dnp->dn_name, "tcp") == 0 ||
8661                     strcmp(dnp->dn_name, "udp") == 0 ||
8662                     strcmp(dnp->dn_name, "icmp") == 0 ||
8663                     strcmp(dnp->dn_name, "tl") == 0 ||
8664                     strcmp(dnp->dn_name, "ip6") == 0 ||
8665                     strcmp(dnp->dn_name, "tcp6") == 0 ||
8666                     strcmp(dnp->dn_name, "udp6") == 0 ||
8667                     strcmp(dnp->dn_name, "icmp6") == 0)) {
8668                         return (B_TRUE);
8669                 }
8670         }
8671         return (B_FALSE);
8672 }