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

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