Print this page
XXXX adding PID information to netstat output


  96 struct socklist socklist;
  97 
  98 struct kmem_cache *socket_cache;
  99 
 100 /*
 101  * sockconf_lock protects the socket configuration (socket types and
 102  * socket filters) which is changed via the sockconfig system call.
 103  */
 104 krwlock_t sockconf_lock;
 105 
 106 static int sockfs_update(kstat_t *, int);
 107 static int sockfs_snapshot(kstat_t *, void *, int);
 108 extern smod_info_t *sotpi_smod_create(void);
 109 
 110 extern void sendfile_init();
 111 
 112 extern void nl7c_init(void);
 113 
 114 extern int modrootloaded;
 115 
 116 #define ADRSTRLEN (2 * sizeof (void *) + 1)
 117 /*
 118  * kernel structure for passing the sockinfo data back up to the user.
 119  * the strings array allows us to convert AF_UNIX addresses into strings
 120  * with a common method regardless of which n-bit kernel we're running.
 121  */
 122 struct k_sockinfo {
 123         struct sockinfo ks_si;
 124         char            ks_straddr[3][ADRSTRLEN];
 125 };
 126 
 127 /*
 128  * Translate from a device pathname (e.g. "/dev/tcp") to a vnode.
 129  * Returns with the vnode held.
 130  */
 131 int
 132 sogetvp(char *devpath, vnode_t **vpp, int uioflag)
 133 {
 134         struct snode *csp;
 135         vnode_t *vp, *dvp;
 136         major_t maj;
 137         int error;
 138 
 139         ASSERT(uioflag == UIO_SYSSPACE || uioflag == UIO_USERSPACE);
 140 
 141         /*
 142          * Lookup the underlying filesystem vnode.
 143          */
 144         error = lookupname(devpath, uioflag, FOLLOW, NULLVPP, &vp);
 145         if (error)
 146                 return (error);


 749          * The latter is needed since we always call fdbuf_free
 750          * which performs a closef.
 751          */
 752         rp = (int *)rights;
 753         for (i = 0; i < numfd; i++) {
 754                 if ((fd = ufalloc(0)) == -1)
 755                         goto cleanup;
 756                 /*
 757                  * We need pointer size alignment for fd_fds. On a LP64
 758                  * kernel, the required alignment is 8 bytes while
 759                  * the option headers and values are only 4 bytes
 760                  * aligned. So its safer to do a bcopy compared to
 761                  * assigning fdbuf->fd_fds[i] to fp.
 762                  */
 763                 bcopy((char *)&fdbuf->fd_fds[i], (char *)&fp, sizeof (fp));
 764                 mutex_enter(&fp->f_tlock);
 765                 fp->f_count++;
 766                 mutex_exit(&fp->f_tlock);
 767                 setf(fd, fp);
 768                 *rp++ = fd;










 769                 if (AU_AUDITING())
 770                         audit_fdrecv(fd, fp);
 771                 dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
 772                     i, fd, (void *)fp, fp->f_count));
 773         }
 774         return (0);
 775 
 776 cleanup:
 777         /*
 778          * Undo whatever partial work the loop above has done.
 779          */
 780         {
 781                 int j;
 782 
 783                 rp = (int *)rights;
 784                 for (j = 0; j < i; j++) {
 785                         dprint(0,
 786                             ("fdbuf_extract: cleanup[%d] = %d\n", j, *rp));
 787                         (void) closeandsetf(*rp++, NULL);
 788                 }


1729         if (ksp != NULL) {
1730                 ASSERT(zoneid == (zoneid_t)(uintptr_t)ksp->ks_private);
1731                 kstat_delete(ksp);
1732         }
1733 }
1734 
1735 /*
1736  * Zones:
1737  * Note that nactive is going to be different for each zone.
1738  * This means we require kstat to call sockfs_update and then sockfs_snapshot
1739  * for the same zone, or sockfs_snapshot will be taken into the wrong size
1740  * buffer. This is safe, but if the buffer is too small, user will not be
1741  * given details of all sockets. However, as this kstat has a ks_lock, kstat
1742  * driver will keep it locked between the update and the snapshot, so no
1743  * other process (zone) can currently get inbetween resulting in a wrong size
1744  * buffer allocation.
1745  */
1746 static int
1747 sockfs_update(kstat_t *ksp, int rw)
1748 {
1749         uint_t  nactive = 0;            /* # of active AF_UNIX sockets  */

1750         struct sonode   *so;            /* current sonode on socklist   */
1751         zoneid_t        myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1752 
1753         ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1754 
1755         if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1756                 return (EACCES);
1757         }
1758 
1759         for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1760                 if (so->so_count != 0 && so->so_zoneid == myzoneid) {

1761                         nactive++;







1762                 }
1763         }
1764         ksp->ks_ndata = nactive;
1765         ksp->ks_data_size = nactive * sizeof (struct k_sockinfo);
1766 
1767         return (0);
1768 }
1769 
1770 static int
1771 sockfs_snapshot(kstat_t *ksp, void *buf, int rw)
1772 {
1773         int                     ns;     /* # of sonodes we've copied    */
1774         struct sonode           *so;    /* current sonode on socklist   */
1775         struct k_sockinfo       *pksi;  /* where we put sockinfo data   */
1776         t_uscalar_t             sn_len; /* soa_len                      */
1777         zoneid_t                myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1778         sotpi_info_t            *sti;
1779 




1780         ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1781 
1782         ksp->ks_snaptime = gethrtime();
1783 
1784         if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1785                 return (EACCES);
1786         }
1787 
1788         /*
1789          * for each sonode on the socklist, we massage the important
1790          * info into buf, in k_sockinfo format.
1791          */
1792         pksi = (struct k_sockinfo *)buf;
1793         ns = 0;
1794         for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1795                 /* only stuff active sonodes and the same zone:         */
1796                 if (so->so_count == 0 || so->so_zoneid != myzoneid) {
1797                         continue;
1798                 }
1799 









1800                 /*
1801                  * If the sonode was activated between the update and the
1802                  * snapshot, we're done - as this is only a snapshot.







1803                  */
1804                 if ((caddr_t)(pksi) >= (caddr_t)buf + ksp->ks_data_size) {

1805                         break;
1806                 }
1807 
1808                 sti = SOTOTPI(so);
1809                 /* copy important info into buf:                        */
1810                 pksi->ks_si.si_size = sizeof (struct k_sockinfo);
1811                 pksi->ks_si.si_family = so->so_family;
1812                 pksi->ks_si.si_type = so->so_type;
1813                 pksi->ks_si.si_flag = so->so_flag;
1814                 pksi->ks_si.si_state = so->so_state;
1815                 pksi->ks_si.si_serv_type = sti->sti_serv_type;
1816                 pksi->ks_si.si_ux_laddr_sou_magic =
1817                     sti->sti_ux_laddr.soua_magic;
1818                 pksi->ks_si.si_ux_faddr_sou_magic =
1819                     sti->sti_ux_faddr.soua_magic;
1820                 pksi->ks_si.si_laddr_soa_len = sti->sti_laddr.soa_len;
1821                 pksi->ks_si.si_faddr_soa_len = sti->sti_faddr.soa_len;
1822                 pksi->ks_si.si_szoneid = so->so_zoneid;
1823                 pksi->ks_si.si_faddr_noxlate = sti->sti_faddr_noxlate;

1824 
1825                 mutex_enter(&so->so_lock);
1826 
1827                 if (sti->sti_laddr_sa != NULL) {
1828                         ASSERT(sti->sti_laddr_sa->sa_data != NULL);
1829                         sn_len = sti->sti_laddr_len;
1830                         ASSERT(sn_len <= sizeof (short) +
1831                             sizeof (pksi->ks_si.si_laddr_sun_path));
1832 
1833                         pksi->ks_si.si_laddr_family =
1834                             sti->sti_laddr_sa->sa_family;
1835                         if (sn_len != 0) {
1836                                 /* AF_UNIX socket names are NULL terminated */
1837                                 (void) strncpy(pksi->ks_si.si_laddr_sun_path,
1838                                     sti->sti_laddr_sa->sa_data,
1839                                     sizeof (pksi->ks_si.si_laddr_sun_path));
1840                                 sn_len = strlen(pksi->ks_si.si_laddr_sun_path);
1841                         }
1842                         pksi->ks_si.si_laddr_sun_path[sn_len] = 0;
1843                 }
1844 
1845                 if (sti->sti_faddr_sa != NULL) {
1846                         ASSERT(sti->sti_faddr_sa->sa_data != NULL);
1847                         sn_len = sti->sti_faddr_len;
1848                         ASSERT(sn_len <= sizeof (short) +
1849                             sizeof (pksi->ks_si.si_faddr_sun_path));
1850 
1851                         pksi->ks_si.si_faddr_family =
1852                             sti->sti_faddr_sa->sa_family;
1853                         if (sn_len != 0) {
1854                                 (void) strncpy(pksi->ks_si.si_faddr_sun_path,
1855                                     sti->sti_faddr_sa->sa_data,
1856                                     sizeof (pksi->ks_si.si_faddr_sun_path));
1857                                 sn_len = strlen(pksi->ks_si.si_faddr_sun_path);
1858                         }
1859                         pksi->ks_si.si_faddr_sun_path[sn_len] = 0;
1860                 }
1861 
1862                 mutex_exit(&so->so_lock);
1863 
1864                 (void) sprintf(pksi->ks_straddr[0], "%p", (void *)so);
1865                 (void) sprintf(pksi->ks_straddr[1], "%p",
1866                     (void *)sti->sti_ux_laddr.soua_vp);
1867                 (void) sprintf(pksi->ks_straddr[2], "%p",
1868                     (void *)sti->sti_ux_faddr.soua_vp);
1869 









1870                 ns++;
1871                 pksi++;
1872         }
1873 
1874         ksp->ks_ndata = ns;
1875         return (0);
1876 }
1877 
1878 ssize_t
1879 soreadfile(file_t *fp, uchar_t *buf, u_offset_t fileoff, int *err, size_t size)
1880 {
1881         struct uio auio;
1882         struct iovec aiov[MSG_MAXIOVLEN];
1883         register vnode_t *vp;
1884         int ioflag, rwflag;
1885         ssize_t cnt;
1886         int error = 0;
1887         int iovcnt = 0;
1888         short fflag;
1889 
1890         vp = fp->f_vnode;
1891         fflag = fp->f_flag;




  96 struct socklist socklist;
  97 
  98 struct kmem_cache *socket_cache;
  99 
 100 /*
 101  * sockconf_lock protects the socket configuration (socket types and
 102  * socket filters) which is changed via the sockconfig system call.
 103  */
 104 krwlock_t sockconf_lock;
 105 
 106 static int sockfs_update(kstat_t *, int);
 107 static int sockfs_snapshot(kstat_t *, void *, int);
 108 extern smod_info_t *sotpi_smod_create(void);
 109 
 110 extern void sendfile_init();
 111 
 112 extern void nl7c_init(void);
 113 
 114 extern int modrootloaded;
 115 











 116 /*
 117  * Translate from a device pathname (e.g. "/dev/tcp") to a vnode.
 118  * Returns with the vnode held.
 119  */
 120 int
 121 sogetvp(char *devpath, vnode_t **vpp, int uioflag)
 122 {
 123         struct snode *csp;
 124         vnode_t *vp, *dvp;
 125         major_t maj;
 126         int error;
 127 
 128         ASSERT(uioflag == UIO_SYSSPACE || uioflag == UIO_USERSPACE);
 129 
 130         /*
 131          * Lookup the underlying filesystem vnode.
 132          */
 133         error = lookupname(devpath, uioflag, FOLLOW, NULLVPP, &vp);
 134         if (error)
 135                 return (error);


 738          * The latter is needed since we always call fdbuf_free
 739          * which performs a closef.
 740          */
 741         rp = (int *)rights;
 742         for (i = 0; i < numfd; i++) {
 743                 if ((fd = ufalloc(0)) == -1)
 744                         goto cleanup;
 745                 /*
 746                  * We need pointer size alignment for fd_fds. On a LP64
 747                  * kernel, the required alignment is 8 bytes while
 748                  * the option headers and values are only 4 bytes
 749                  * aligned. So its safer to do a bcopy compared to
 750                  * assigning fdbuf->fd_fds[i] to fp.
 751                  */
 752                 bcopy((char *)&fdbuf->fd_fds[i], (char *)&fp, sizeof (fp));
 753                 mutex_enter(&fp->f_tlock);
 754                 fp->f_count++;
 755                 mutex_exit(&fp->f_tlock);
 756                 setf(fd, fp);
 757                 *rp++ = fd;
 758 
 759                 /*
 760                  * Add the current pid to the list associated with this
 761                  * descriptor.
 762                  */
 763                 if (fp->f_vnode != NULL)
 764                         (void) VOP_IOCTL(fp->f_vnode, F_ASSOCI_PID,
 765                             (intptr_t)curproc->p_pidp->pid_id, FKIOCTL, kcred,
 766                             NULL, NULL);
 767 
 768                 if (AU_AUDITING())
 769                         audit_fdrecv(fd, fp);
 770                 dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
 771                     i, fd, (void *)fp, fp->f_count));
 772         }
 773         return (0);
 774 
 775 cleanup:
 776         /*
 777          * Undo whatever partial work the loop above has done.
 778          */
 779         {
 780                 int j;
 781 
 782                 rp = (int *)rights;
 783                 for (j = 0; j < i; j++) {
 784                         dprint(0,
 785                             ("fdbuf_extract: cleanup[%d] = %d\n", j, *rp));
 786                         (void) closeandsetf(*rp++, NULL);
 787                 }


1728         if (ksp != NULL) {
1729                 ASSERT(zoneid == (zoneid_t)(uintptr_t)ksp->ks_private);
1730                 kstat_delete(ksp);
1731         }
1732 }
1733 
1734 /*
1735  * Zones:
1736  * Note that nactive is going to be different for each zone.
1737  * This means we require kstat to call sockfs_update and then sockfs_snapshot
1738  * for the same zone, or sockfs_snapshot will be taken into the wrong size
1739  * buffer. This is safe, but if the buffer is too small, user will not be
1740  * given details of all sockets. However, as this kstat has a ks_lock, kstat
1741  * driver will keep it locked between the update and the snapshot, so no
1742  * other process (zone) can currently get inbetween resulting in a wrong size
1743  * buffer allocation.
1744  */
1745 static int
1746 sockfs_update(kstat_t *ksp, int rw)
1747 {
1748         uint_t  n, nactive = 0;         /* # of active AF_UNIX sockets  */
1749         uint_t  tsze  = 0;
1750         struct sonode   *so;            /* current sonode on socklist   */
1751         zoneid_t        myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1752 
1753         ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1754 
1755         if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1756                 return (EACCES);
1757         }
1758 
1759         for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1760                 if (so->so_count != 0 && so->so_zoneid == myzoneid) {
1761 
1762                         nactive++;
1763 
1764                         mutex_enter(&so->so_pid_tree_lock);
1765                         n = avl_numnodes(&so->so_pid_tree);
1766                         mutex_exit(&so->so_pid_tree_lock);
1767 
1768                         tsze += sizeof (struct sockinfo);
1769                         tsze += (n > 1) ? ((n - 1) * sizeof (pid_t)) : 0;
1770                 }
1771         }
1772         ksp->ks_ndata = nactive;
1773         ksp->ks_data_size = tsze;
1774 
1775         return (0);
1776 }
1777 
1778 static int
1779 sockfs_snapshot(kstat_t *ksp, void *buf, int rw)
1780 {
1781         int                     ns;     /* # of sonodes we've copied    */
1782         struct sonode           *so;    /* current sonode on socklist   */
1783         struct sockinfo         *psi;   /* where we put sockinfo data   */
1784         t_uscalar_t             sn_len; /* soa_len                      */
1785         zoneid_t                myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1786         sotpi_info_t            *sti;
1787 
1788         uint_t                          sze;
1789         mblk_t                          *mblk;
1790         conn_pid_info_t                 *cpi;
1791 
1792         ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1793 
1794         ksp->ks_snaptime = gethrtime();
1795 
1796         if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1797                 return (EACCES);
1798         }
1799 
1800         /*
1801          * for each sonode on the socklist, we massage the important
1802          * info into buf, in k_sockinfo format.
1803          */
1804         psi = (struct sockinfo *)buf;
1805         ns = 0;
1806         for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1807                 /* only stuff active sonodes and the same zone:         */
1808                 if (so->so_count == 0 || so->so_zoneid != myzoneid) {
1809                         continue;
1810                 }
1811 
1812                 mblk = so_get_sock_pid_mblk((sock_upper_handle_t)so);
1813                 if (mblk == NULL) {
1814                         continue;
1815                 }
1816                 cpi = (conn_pid_info_t *)mblk->b_datap->db_base;
1817                 sze = sizeof (struct sockinfo);
1818                 sze += (cpi->cpi_pids_cnt > 1) ?
1819                     ((cpi->cpi_pids_cnt - 1) * sizeof (pid_t)) : 0;
1820 
1821                 /*
1822                  * If the sonode was activated between the update and the
1823                  * snapshot, we're done - as this is only a snapshot. We need
1824                  * to make sure that we have space for this sockinfo. In the
1825                  * time window between the update and the snapshot, the size of
1826                  * sockinfo may change, as new pids are added/removed to/from
1827                  * the list. We have to take that into consideration and only
1828                  * include the sockinfo if we have enough space. That means the
1829                  * number of entries we return by snapshot might not equal the
1830                  * the number of entries calculated by update.
1831                  */
1832                 if (((caddr_t)(psi) + sze) >
1833                     ((caddr_t)buf + ksp->ks_data_size)) {
1834                         break;
1835                 }
1836 
1837                 sti = SOTOTPI(so);
1838                 /* copy important info into buf:                        */
1839                 psi->si_size = sze;
1840                 psi->si_family = so->so_family;
1841                 psi->si_type = so->so_type;
1842                 psi->si_flag = so->so_flag;
1843                 psi->si_state = so->so_state;
1844                 psi->si_serv_type = sti->sti_serv_type;
1845                 psi->si_ux_laddr_sou_magic =
1846                     sti->sti_ux_laddr.soua_magic;
1847                 psi->si_ux_faddr_sou_magic =
1848                     sti->sti_ux_faddr.soua_magic;
1849                 psi->si_laddr_soa_len = sti->sti_laddr.soa_len;
1850                 psi->si_faddr_soa_len = sti->sti_faddr.soa_len;
1851                 psi->si_szoneid = so->so_zoneid;
1852                 psi->si_faddr_noxlate = sti->sti_faddr_noxlate;
1853 
1854 
1855                 mutex_enter(&so->so_lock);
1856 
1857                 if (sti->sti_laddr_sa != NULL) {
1858                         ASSERT(sti->sti_laddr_sa->sa_data != NULL);
1859                         sn_len = sti->sti_laddr_len;
1860                         ASSERT(sn_len <= sizeof (short) +
1861                             sizeof (psi->si_laddr_sun_path));
1862 
1863                         psi->si_laddr_family =
1864                             sti->sti_laddr_sa->sa_family;
1865                         if (sn_len != 0) {
1866                                 /* AF_UNIX socket names are NULL terminated */
1867                                 (void) strncpy(psi->si_laddr_sun_path,
1868                                     sti->sti_laddr_sa->sa_data,
1869                                     sizeof (psi->si_laddr_sun_path));
1870                                 sn_len = strlen(psi->si_laddr_sun_path);
1871                         }
1872                         psi->si_laddr_sun_path[sn_len] = 0;
1873                 }
1874 
1875                 if (sti->sti_faddr_sa != NULL) {
1876                         ASSERT(sti->sti_faddr_sa->sa_data != NULL);
1877                         sn_len = sti->sti_faddr_len;
1878                         ASSERT(sn_len <= sizeof (short) +
1879                             sizeof (psi->si_faddr_sun_path));
1880 
1881                         psi->si_faddr_family =
1882                             sti->sti_faddr_sa->sa_family;
1883                         if (sn_len != 0) {
1884                                 (void) strncpy(psi->si_faddr_sun_path,
1885                                     sti->sti_faddr_sa->sa_data,
1886                                     sizeof (psi->si_faddr_sun_path));
1887                                 sn_len = strlen(psi->si_faddr_sun_path);
1888                         }
1889                         psi->si_faddr_sun_path[sn_len] = 0;
1890                 }
1891 
1892                 mutex_exit(&so->so_lock);
1893 
1894                 (void) sprintf(psi->si_son_straddr, "%p", (void *)so);
1895                 (void) sprintf(psi->si_lvn_straddr, "%p",
1896                     (void *)sti->sti_ux_laddr.soua_vp);
1897                 (void) sprintf(psi->si_fvn_straddr, "%p",
1898                     (void *)sti->sti_ux_faddr.soua_vp);
1899 
1900                 psi->si_pids[0] = 0;
1901                 if ((psi->si_pn_cnt = cpi->cpi_pids_cnt) > 0) {
1902                         (void) memcpy(psi->si_pids, cpi->cpi_pids,
1903                             psi->si_pn_cnt * sizeof (pid_t));
1904                 }
1905 
1906                 freemsg(mblk);
1907 
1908                 psi = (struct sockinfo *)((caddr_t)psi + psi->si_size);
1909                 ns++;

1910         }
1911 
1912         ksp->ks_ndata = ns;
1913         return (0);
1914 }
1915 
1916 ssize_t
1917 soreadfile(file_t *fp, uchar_t *buf, u_offset_t fileoff, int *err, size_t size)
1918 {
1919         struct uio auio;
1920         struct iovec aiov[MSG_MAXIOVLEN];
1921         register vnode_t *vp;
1922         int ioflag, rwflag;
1923         ssize_t cnt;
1924         int error = 0;
1925         int iovcnt = 0;
1926         short fflag;
1927 
1928         vp = fp->f_vnode;
1929         fflag = fp->f_flag;