blob: fc54f8363df0d02bda6993effec944f45abcdeb4 [file] [log] [blame]
/*
* dsock.c - /dev/kmem-based HP-UX socket processing functions for lsof
*/
/*
* Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
* 47907. All rights reserved.
*
* Written by Victor A. Abell
*
* This software is not subject to any license of the American Telephone
* and Telegraph Company or the Regents of the University of California.
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
*
* 1. Neither the authors nor Purdue University are responsible for any
* consequences of the use of this software.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Credit to the authors and Purdue
* University must appear in documentation and sources.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 4. This notice may not be removed or altered.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dsock.c,v 1.20 2005/08/08 19:50:23 abe Exp $";
#endif
#if defined(HPUXKERNBITS) && HPUXKERNBITS>=64
#define _INO_T
typedef int ino_t;
#define _TIME_T
typedef int time_t;
#endif /* defined(HPUXKERNBITS) && HPUXKERNBITS>=64 */
#include "lsof.h"
#if HPUXV>=800 && defined(HPUX_CCITT)
#include <x25/x25addrstr.h>
#include <x25/x25stat.h>
#include <x25/x25str.h>
#include <x25/x25config.h>
#include <x25/x25L3.h>
#endif /* HPUXV>=800 && defined(HPUX_CCITT) */
/*
* Local definitions
*/
#if defined(HASTCPOPT)
#define TF_NODELAY 0x1 /* TCP_NODELAY (Nagle algorithm) */
#endif /* defined(HASTCPOPT) */
#if HPUXV>=1030
/*
* print_tcptpi() - print TCP/TPI info
*/
void
print_tcptpi(nl)
int nl; /* 1 == '\n' required */
{
char *cp = (char *)NULL;
char sbuf[128];
int i, t;
int ps = 0;
unsigned int u;
if (Ftcptpi & TCPTPI_STATE) {
switch ((t = Lf->lts.type)) {
case 0: /* TCP */
switch ((i = Lf->lts.state.i)) {
case TCPS_CLOSED:
cp = "CLOSED";
break;
case TCPS_IDLE:
cp = "IDLE";
break;
case TCPS_BOUND:
cp = "BOUND";
break;
case TCPS_LISTEN:
cp = "LISTEN";
break;
case TCPS_SYN_SENT:
cp = "SYN_SENT";
break;
case TCPS_SYN_RCVD:
cp = "SYN_RCVD";
break;
case TCPS_ESTABLISHED:
cp = "ESTABLISHED";
break;
case TCPS_CLOSE_WAIT:
cp = "CLOSE_WAIT";
break;
case TCPS_FIN_WAIT_1:
cp = "FIN_WAIT_1";
break;
case TCPS_CLOSING:
cp = "CLOSING";
break;
case TCPS_LAST_ACK:
cp = "LAST_ACK";
break;
case TCPS_FIN_WAIT_2:
cp = "FIN_WAIT_2";
break;
case TCPS_TIME_WAIT:
cp = "TIME_WAIT";
break;
default:
(void) snpf(sbuf, sizeof(sbuf), "UknownState_%d", i);
cp = sbuf;
}
break;
case 1: /* TPI */
switch ((u = Lf->lts.state.ui)) {
case TS_UNINIT:
cp = "Uninitialized";
break;
case TS_UNBND:
cp = "Unbound";
break;
case TS_WACK_BREQ:
cp = "Wait_BIND_REQ_Ack";
break;
case TS_WACK_UREQ:
cp = "Wait_UNBIND_REQ_Ack";
break;
case TS_IDLE:
cp = "Idle";
break;
case TS_WACK_OPTREQ:
cp = "Wait_OPT_REQ_Ack";
break;
case TS_WACK_CREQ:
cp = "Wait_CONN_REQ_Ack";
break;
case TS_WCON_CREQ:
cp = "Wait_CONN_REQ_Confirm";
break;
case TS_WRES_CIND:
cp = "Wait_CONN_IND_Response";
break;
case TS_WACK_CRES:
cp = "Wait_CONN_RES_Ack";
break;
case TS_DATA_XFER:
cp = "Wait_Data_Xfr";
break;
case TS_WIND_ORDREL:
cp = "Wait_Read_Release";
break;
case TS_WREQ_ORDREL:
cp = "Wait_Write_Release";
break;
case TS_WACK_DREQ6:
case TS_WACK_DREQ7:
case TS_WACK_DREQ9:
case TS_WACK_DREQ10:
case TS_WACK_DREQ11:
cp = "Wait_DISCON_REQ_Ack";
break;
case TS_WACK_ORDREL:
cp = "Internal";
break;
default:
(void) snpf(sbuf, sizeof(sbuf), "UNKNOWN_TPI_STATE_%u", u);
cp = sbuf;
}
}
if (Ffield)
(void) printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator);
else {
putchar('(');
(void) fputs(cp, stdout);
}
ps++;
}
# if defined(HASTCPTPIQ)
if (Ftcptpi & TCPTPI_QUEUES) {
if (Lf->lts.rqs) {
if (Ffield)
putchar(LSOF_FID_TCPTPI);
else {
if (ps)
putchar(' ');
else
putchar('(');
}
(void) printf("QR=%lu", Lf->lts.rq);
if (Ffield)
putchar(Terminator);
ps++;
}
if (Lf->lts.sqs) {
if (Ffield)
putchar(LSOF_FID_TCPTPI);
else {
if (ps)
putchar(' ');
else
putchar('(');
}
(void) printf("QS=%lu", Lf->lts.sq);
if (Ffield)
putchar(Terminator);
ps++;
}
}
# endif /* defined(HASTCPTPIQ) */
#if defined(HASSOOPT)
if (Ftcptpi & TCPTPI_FLAGS) {
int opt;
if ((opt = Lf->lts.opt)
|| Lf->lts.qlens || Lf->lts.qlims || Lf->lts.rbszs || Lf->lts.sbsz
) {
char sep = ' ';
if (Ffield)
sep = LSOF_FID_TCPTPI;
else if (!ps)
sep = '(';
(void) printf("%cSO", sep);
ps++;
sep = '=';
# if defined(SO_BROADCAST)
if (opt & SO_BROADCAST) {
(void) printf("%cBROADCAST", sep);
opt &= ~SO_BROADCAST;
sep = ',';
}
# endif /* defined(SO_BROADCAST) */
# if defined(SO_DEBUG)
if (opt & SO_DEBUG) {
(void) printf("%cDEBUG", sep);
opt &= ~ SO_DEBUG;
sep = ',';
}
# endif /* defined(SO_DEBUG) */
# if defined(SO_DONTROUTE)
if (opt & SO_DONTROUTE) {
(void) printf("%cDONTROUTE", sep);
opt &= ~SO_DONTROUTE;
sep = ',';
}
# endif /* defined(SO_DONTROUTE) */
# if defined(SO_KEEPALIVE)
if (opt & SO_KEEPALIVE) {
(void) printf("%cKEEPALIVE", sep);
if (Lf->lts.kai)
(void) printf("=%d", Lf->lts.kai);
opt &= ~SO_KEEPALIVE;
sep = ',';
}
# endif /* defined(SO_KEEPALIVE) */
# if defined(SO_LINGER)
if (opt & SO_LINGER) {
(void) printf("%cLINGER", sep);
if (Lf->lts.ltm)
(void) printf("=%d", Lf->lts.ltm);
opt &= ~SO_LINGER;
sep = ',';
}
# endif /* defined(SO_LINGER) */
# if defined(SO_OOBINLINE)
if (opt & SO_OOBINLINE) {
(void) printf("%cOOBINLINE", sep);
opt &= ~SO_OOBINLINE;
sep = ',';
}
# endif /* defined(SO_OOBINLINE) */
if (Lf->lts.qlens) {
(void) printf("%cQLEN=%u", sep, Lf->lts.qlen);
sep = ',';
}
if (Lf->lts.qlims) {
(void) printf("%cQLIM=%u", sep, Lf->lts.qlim);
sep = ',';
}
# if defined(SO_REUSEADDR)
if (opt & SO_REUSEADDR) {
(void) printf("%cREUSEADDR", sep);
opt &= ~SO_REUSEADDR;
sep = ',';
}
# endif /* defined(SO_REUSEADDR) */
# if defined(SO_REUSEPORT)
if (opt & SO_REUSEPORT) {
(void) printf("%cREUSEPORT", sep);
opt &= ~SO_REUSEPORT;
sep = ',';
}
# endif /* defined(SO_REUSEPORT) */
# if defined(SO_USELOOPBACK)
if (opt & SO_USELOOPBACK) {
(void) printf("%cUSELOOPBACK", sep);
opt &= ~SO_USELOOPBACK;
sep = ',';
}
# endif /* defined(SO_USELOOPBACK) */
if (opt)
(void) printf("%cUNKNOWN=%#x", sep, opt);
if (Ffield)
putchar(Terminator);
}
}
#endif /* defined(HASSOOPT) */
#if defined(HASTCPOPT)
if (Ftcptpi & TCPTPI_FLAGS) {
int topt;
if ((topt = Lf->lts.topt) || Lf->lts.msss) {
char sep = ' ';
if (Ffield)
sep = LSOF_FID_TCPTPI;
else if (!ps)
sep = '(';
(void) printf("%cTF", sep);
ps++;
sep = '=';
if (Lf->lts.msss) {
(void) printf("%cMSS=%lu", sep, Lf->lts.mss);
sep = ',';
}
# if defined(TF_NODELAY)
if (topt & TF_NODELAY) {
(void) printf("%cNODELAY", sep);
topt &= ~TF_NODELAY;
sep = ',';
}
# endif /* defined(TF_NODELAY) */
if (topt)
(void) printf("%cUNKNOWN=%#x", sep, topt);
if (Ffield)
putchar(Terminator);
}
}
# endif /* defined(HASTCPOPT) */
# if defined(HASTCPTPIW)
if (Ftcptpi & TCPTPI_WINDOWS) {
if (Lf->lts.rws) {
if (Ffield)
putchar(LSOF_FID_TCPTPI);
else {
if (ps)
putchar(' ');
else
putchar('(');
}
(void) printf("WR=%lu", Lf->lts.rw);
if (Ffield)
putchar(Terminator);
ps++;
}
if (Lf->lts.wws) {
if (Ffield)
putchar(LSOF_FID_TCPTPI);
else {
if (ps)
putchar(' ');
else
putchar('(');
}
(void) printf("WW=%lu", Lf->lts.ww);
if (Ffield)
putchar(Terminator);
ps++;
}
}
# endif /* defined(HASTCPTPIW) */
if (Ftcptpi && !Ffield && ps)
putchar(')');
if (nl)
putchar('\n');
}
#endif /* HPUXV>=1030 */
#if defined(DTYPE_LLA)
/*
* process_lla() - process link level access socket file
*/
void
process_lla(la)
KA_T la; /* link level CB address in kernel */
{
char *ep;
struct lla_cb lcb;
size_t sz;
(void) snpf(Lf->type, sizeof(Lf->type), "lla");
Lf->inp_ty = 2;
enter_dev_ch(print_kptr(la, (char *)NULL, 0));
/*
* Read link level access control block.
*/
if (!la || kread((KA_T)la, (char *)&lcb, sizeof(lcb))) {
(void) snpf(Namech, Namechl, "can't read LLA CB (%s)",
print_kptr(la, (char *)NULL, 0));
enter_nm(Namech);
return;
}
/*
* Determine access mode.
*/
if ((lcb.lla_flags & LLA_FWRITE | LLA_FREAD) == LLA_FWRITE)
Lf->access = 'w';
else if ((lcb.lla_flags & LLA_FWRITE | LLA_FREAD) == LLA_FREAD)
Lf->access = 'r';
else if (lcb.lla_flags & LLA_FWRITE | LLA_FREAD)
Lf->access = 'u';
/*
* Determine the open mode, if possible.
*/
if (lcb.lla_flags & LLA_IS_ETHER)
(void) snpf(Lf->iproto, sizeof(Lf->iproto), "Ether");
else if (lcb.lla_flags & (LLA_IS_8025|LLA_IS_SNAP8025|LLA_IS_FA8025)) {
(void) snpf(Lf->iproto, sizeof(Lf->iproto), "802.5");
if (lcb.lla_flags & LLA_IS_SNAP8025)
(void) snpf(Namech, Namechl, "SNAP");
else if (lcb.lla_flags & LLA_IS_FA8025)
(void) snpf(Namech, Namechl, "function address");
}
/*
* Add any significant flags.
*/
if (lcb.lla_flags & ~(LLA_FWRITE | LLA_FREAD)) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%s(flags = %#x)",
(ep == Namech) ? "" : " ",
lcb.lla_flags);
}
if (Namech[0])
enter_nm(Namech);
}
#endif /* DTYPE_LLA */
/*
* process_socket() - process socket
*/
void
process_socket(sa)
KA_T sa; /* socket address in kernel */
{
unsigned char *fa = (unsigned char *)NULL;
char *ep, tbuf[32];
int fam;
int fp, mbl, lp;
unsigned char *la = (unsigned char *)NULL;
struct protosw p;
struct socket s;
size_t sz;
struct unpcb uc, unp;
struct sockaddr_un *ua = (struct sockaddr_un *)NULL;
struct sockaddr_un un;
#if HPUXV>=800
struct domain d;
# if defined(HPUX_CCITT)
int i;
struct x25pcb xp;
struct x25pcb_extension xpe;
# endif /* defined(HPUX_CCITT) */
# if HPUXV<1030
struct mbuf mb;
struct inpcb inp;
struct rawcb raw;
struct tcpcb t;
# else /* HPUXV>=1030 */
struct datab db;
static char *dbf = (char *)NULL;
static int dbl = 0;
struct msgb mb;
struct sockbuf rb, sb;
# endif /* HPUXV<1030 */
#endif /* HPUXV>=800 */
(void) snpf(Lf->type, sizeof(Lf->type), "sock");
Lf->inp_ty = 2;
/*
* Read socket structure.
*/
if (!sa) {
enter_nm("no socket address");
return;
}
if (kread((KA_T) sa, (char *) &s, sizeof(s))) {
(void) snpf(Namech, Namechl, "can't read socket struct from %s",
print_kptr(sa, (char *)NULL, 0));
enter_nm(Namech);
return;
}
/*
* Read protocol switch and domain structure (HP-UX 8 and above).
*/
if (!s.so_type) {
(void) snpf(Namech, Namechl, "no socket type");
enter_nm(Namech);
return;
}
if (!s.so_proto
|| kread((KA_T) s.so_proto, (char *) &p, sizeof(p))) {
(void) snpf(Namech, Namechl, "no protocol switch");
enter_nm(Namech);
return;
}
#if HPUXV>=800
if (kread((KA_T) p.pr_domain, (char *) &d, sizeof(d))) {
(void) snpf(Namech, Namechl, "can't read domain struct from %s",
print_kptr((KA_T)p.pr_domain, (char *)NULL, 0));
enter_nm(Namech);
return;
}
#endif /* HPUXV>=800 */
#if HPUXV<1030
/*
* Save size information for HP-UX < 10.30.
*/
if (Fsize) {
if (Lf->access == 'r')
Lf->sz = (SZOFFTYPE)s.so_rcv.sb_cc;
else if (Lf->access == 'w')
Lf->sz = (SZOFFTYPE)s.so_snd.sb_cc;
else
Lf->sz = (SZOFFTYPE)(s.so_rcv.sb_cc + s.so_snd.sb_cc);
Lf->sz_def = 1;
} else
Lf->off_def = 1;
# if defined(HASTCPTPIQ)
Lf->lts.rq = s.so_rcv.sb_cc;
Lf->lts.sq = s.so_snd.sb_cc;
Lf->lts.rqs = Lf->lts.sqs = 1;
# endif /* defined(HASTCPTPIQ) */
#endif /* HPUXV<1030 */
/*
* Process socket by the associated domain family.
*/
#if HPUXV>=800
switch ((fam = d.dom_family))
#else /* HPUXV<800 */
switch ((fam = p.pr_family))
#endif /* HPUXV>=800 */
{
#if HPUXV>=800 && HPUXV<1030 && defined(HPUX_CCITT)
/*
* Process an HP-UX [89].x CCITT X25 domain socket.
*/
case AF_CCITT:
if (Fnet)
Lf->sf |= SELNET;
(void) snpf(Lf->type, sizeof(Lf->type), "x.25");
(void) snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL,
"CCITT");
/*
* Get the X25 PCB and its extension.
*/
if (!s.so_pcb
|| kread((KA_T)s.so_pcb, (char *)&xp, sizeof(xp))) {
(void) snpf(Namech, Namechl, "can't read x.25 pcb at %s",
print_kptr((KA_T)s.so_pcb, (char *)NULL, 0));
enter_nm(Namech);
return;
}
enter_dev_ch(print_kptr((KA_T)s.so_pcb, (char *)NULL, 0));
if (!xp.x25pcb_extend
|| kread((KA_T)xp.x25pcb_extend, (char *)&xpe, sizeof(xpe))) {
(void) snpf(Namech, Namechl,
"can't read x.25 pcb (%s) extension at %s",
print_kptr((KA_T)s.so_pcb, tbuf, sizeof(tbuf)),
print_kptr((KA_T)xp.x25pcb_extend, (char *)NULL, 0));
enter_nm(Namech);
return;
}
/*
* Format local address.
*/
for (i = 0; i < xpe.x25pcbx_local_addr.x25hostlen/2; i++) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%02x", xpe.x25pcbx_local_addr.x25_host[i]);
}
if (i*2 != xpe.x25pcbx_local_addr.x25hostlen) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%01x",
xpe.x25pcbx_local_addr.x25_host[i] >> 4);
}
/*
* Display the virtual connection number, if it's defined.
*/
if (xp.x25pcb_vcn >= 0) {
ep = endnm(&sz);
(void) snpf(ep, sz, ":%d", xp.x25pcb_vcn + 1);
}
/*
* Format peer address, if there is one.
*/
if (xpe.x25pcbx_peer_addr.x25hostlen > 0) {
ep = endnm(&sz);
(void) snpf(ep, sz, "->");
for (i = 0; i < xpe.x25pcbx_peer_addr.x25hostlen/2; i++) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%02x",
xpe.x25pcbx_peer_addr.x25_host[i]);
}
if (i*2 != xpe.x25pcbx_peer_addr.x25hostlen) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%01x",
xpe.x25pcbx_peer_addr.x25_host[i] >> 4);
}
}
enter_nm(Namech);
break;
#endif /* HPUXV>=800 && HPUXV<1030 && defined(HPUX_CCITT) */
/*
* Process an Internet domain socket.
*/
case AF_INET:
if (Fnet)
Lf->sf |= SELNET;
(void) snpf(Lf->type, sizeof(Lf->type), "inet");
printiproto(p.pr_protocol);
#if HPUXV>=1030
/*
* Handle HP-UX 10.30 and above socket streams.
*/
if (s.so_sth) {
KA_T ip, pcb;
char *pn = (char *)NULL;
/*
* Read module information.
*/
if (read_mi((KA_T)s.so_sth, &ip, &pcb, &pn))
return;
if (ip && pcb) {
/*
* If IP and TCP or UDP modules are present, process as a
* stream socket.
*/
process_stream_sock(ip, pcb, pn, VNON);
return;
}
/*
* If an IP module's PCB address is present, print it as the
* device characters.
*/
if (ip && !Lf->dev_def)
enter_dev_ch(print_kptr(ip, (char *)NULL, 0));
if (!strlen(Namech)) {
/*
* If there are no NAME field characters, enter an error
* message.
*/
if (!ip) {
(void) snpf(Namech, Namechl,
"no IP module for stream socket");
} else {
(void) snpf(Namech, Namechl,
"no TCP/UDP module for stream socket");
}
}
enter_nm(Namech);
return;
}
#else /* HPUXV<1030 */
/*
* Read protocol control block.
*/
if (!s.so_pcb) {
enter_nm("no protocol control block");
return;
}
if (s.so_type == SOCK_RAW) {
/*
* Print raw socket information.
*/
if (kread((KA_T)s.so_pcb, (char *)&raw, sizeof(raw))
|| (struct socket *)sa != (struct socket *)raw.rcb_socket) {
(void) snpf(Namech, Namechl, "can't read rawcb at %s",
print_kptr((KA_T)s.so_pcb, (char *)NULL, 0));
enter_nm(Namech);
return;
}
enter_dev_ch(print_kptr((KA_T)(raw.rcb_pcb ? raw.rcb_pcb
: s.so_pcb),
(char *)NULL, 0));
if (raw.rcb_laddr.sa_family == AF_INET)
la = (unsigned char *)&raw.rcb_laddr.sa_data[2];
else if (raw.rcb_laddr.sa_family)
printrawaddr(&raw.rcb_laddr);
if (raw.rcb_faddr.sa_family == AF_INET)
fa = (unsigned char *)&raw.rcb_faddr.sa_data[2];
else if (raw.rcb_faddr.sa_family) {
ep = endnm(&sz);
(void) snpf(ep, sz, "->");
printrawaddr(&raw.rcb_faddr);
}
if (fa || la)
(void) ent_inaddr(la, -1, fa, -1, AF_INET);
} else {
/*
* Print Internet socket information.
*/
if (kread((KA_T)s.so_pcb, (char *)&inp, sizeof(inp))) {
(void) snpf(Namech, Namechl, "can't read inpcb at %s",
print_kptr((KA_T)s.so_pcb, (char *)NULL, 0));
enter_nm(Namech);
return;
}
enter_dev_ch(print_kptr((KA_T)(inp.inp_ppcb ? inp.inp_ppcb
: s.so_pcb),
(char *)NULL, 0));
la = (unsigned char *)&inp.inp_laddr;
lp = (int)ntohs(inp.inp_lport);
if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) {
fa = (unsigned char *)&inp.inp_faddr;
fp = (int)ntohs(inp.inp_fport);
}
if (fa || la)
(void) ent_inaddr(la, lp, fa, fp, AF_INET);
if (p.pr_protocol == IPPROTO_TCP && inp.inp_ppcb
&& kread((KA_T)inp.inp_ppcb, (char *)&t, sizeof(t)) == 0) {
Lf->lts.type = 0;
Lf->lts.state.i = (int)t.t_state;
}
}
break;
#endif /* HPUXV>=1030 */
/*
* Process a Unix domain socket.
*/
case AF_UNIX:
if (Funix)
Lf->sf |= SELUNX;
(void) snpf(Lf->type, sizeof(Lf->type), "unix");
#if HPUXV>=1030
/*
* Save size information for HP-UX 10.30 and above.
*/
if (Fsize) {
if (!s.so_rcv
|| kread((KA_T)s.so_rcv, (char *)&rb, sizeof(rb)))
rb.sb_cc = 0;
if (!s.so_snd
|| kread((KA_T)s.so_snd, (char *)&sb, sizeof(sb)))
sb.sb_cc = 0;
if (Lf->access == 'r')
Lf->sz = (SZOFFTYPE)rb.sb_cc;
else if (Lf->access == 'w')
Lf->sz = (SZOFFTYPE)sb.sb_cc;
else
Lf->sz = (SZOFFTYPE)(rb.sb_cc + sb.sb_cc);
Lf->sz_def = 1;
} else
Lf->off_def = 1;
#endif /* HPUXV>=1030 */
/*
* Read Unix protocol control block and the Unix address structure.
*/
enter_dev_ch(print_kptr(sa, (char *)NULL, 0));
if (kread((KA_T) s.so_pcb, (char *) &unp, sizeof(unp))) {
(void) snpf(Namech, Namechl, "can't read unpcb at %s",
print_kptr((KA_T)s.so_pcb, (char *)NULL, 0));
break;
}
if ((struct socket *)sa != unp.unp_socket) {
(void) snpf(Namech, Namechl, "unp_socket (%s) mismatch",
print_kptr((KA_T)unp.unp_socket, (char *)NULL, 0));
break;
}
#if HPUXV<1030
/*
* Read UNIX domain socket address information for HP-UX below 10.30.
*/
if (unp.unp_addr) {
if (kread((KA_T) unp.unp_addr, (char *) &mb, sizeof(mb))) {
(void) snpf(Namech, Namechl, "can't read unp_addr at %s",
print_kptr((KA_T)unp.unp_addr, (char *)NULL, 0));
break;
}
ua = (struct sockaddr_un *)(((char *)&mb) + mb.m_off);
mbl = mb.m_len;
}
#else /* HPUXV>=1030 */
/*
* Obtain UNIX domain socket address information for HP-UX 10.30 and
* above.
*/
if (unp.unp_ino) {
Lf->inode = (INODETYPE)unp.unp_ino;
Lf->inp_ty = 1;
}
ua = (struct sockaddr_un *)NULL;
mbl = 0;
if (unp.unp_addr
&& kread((KA_T)unp.unp_addr, (char *)&mb, sizeof(mb)) == 0
&& mb.b_datap
&& kread((KA_T)mb.b_datap, (char *)&db, sizeof(db)) == 0) {
if (db.db_base) {
if (dbl < (db.db_size + 1)) {
dbl = db.db_size + 1;
if (dbf)
dbf = (char *)realloc((MALLOC_P *)dbf,
(MALLOC_S) dbl);
else
dbf = (char *)malloc((MALLOC_S)dbl);
if (!dbf) {
(void) fprintf(stderr,
"%s: no space (%d) for UNIX socket address\n",
Pn, dbl);
Exit(1);
}
}
if (kread((KA_T)db.db_base, dbf, db.db_size) == 0) {
mbl = db.db_size;
dbf[mbl] = '\0';
ua = (struct sockaddr_un *)dbf;
}
}
}
#endif /* HPUXV>=1030 */
if (!ua) {
ua = &un;
(void) bzero((char *)ua, sizeof(un));
ua->sun_family = AF_UNSPEC;
}
/*
* Print information on Unix socket that has no address bound
* to it, although it may be connected to another Unix domain
* socket as a pipe.
*/
if (ua->sun_family != AF_UNIX) {
if (ua->sun_family == AF_UNSPEC) {
if (unp.unp_conn) {
if (kread((KA_T)unp.unp_conn, (char *) &uc, sizeof(uc)))
(void) snpf(Namech, Namechl,
"can't read unp_conn at %s",
print_kptr((KA_T)unp.unp_conn,(char *)NULL,0));
else
(void) snpf(Namech, Namechl, "->%s",
print_kptr((KA_T)uc.unp_socket,(char *)NULL,0));
} else
(void) snpf(Namech, Namechl, "->(none)");
} else
(void) snpf(Namech, Namechl, "unknown sun_family (%d)",
ua->sun_family);
break;
}
if (ua->sun_path[0]) {
if (mbl >= sizeof(struct sockaddr_un))
mbl = sizeof(struct sockaddr_un) - 1;
*((char *)ua + mbl) = '\0';
if (Sfile && is_file_named(ua->sun_path, 0))
Lf->sf |= SELNM;
if (!Namech[0])
(void) snpf(Namech, Namechl, "%s", ua->sun_path);
} else
(void) snpf(Namech, Namechl, "no address");
break;
default:
printunkaf(fam, 1);
}
if (Namech[0])
enter_nm(Namech);
}
#if HPUXV>=1030
/*
* process_stream_sock() - process stream socket
*/
void
process_stream_sock(ip, pcb, pn, vt)
KA_T ip; /* IP module's q_ptr */
KA_T pcb; /* protocol's q_ptr */
char *pn; /* protocol name */
enum vtype vt; /* vnode type */
{
unsigned char *fa = (unsigned char *)NULL;
char *ep;
int fp, lp, rq, sq;
struct ipc_s ic;
unsigned char *la = (unsigned char *)NULL;
size_t sz;
u_short pt;
struct tcp_s tc;
tcph_t th;
struct udp_s ud;
/*
* Set file type and protocol. If AF_INET selection is in effect, set its flag.
*/
if (Fnet)
Lf->sf |= SELNET;
(void) snpf(Lf->type, sizeof(Lf->type), "inet");
if (pn) {
(void) snpf(Lf->iproto, sizeof(Lf->iproto), pn);
Lf->inp_ty = 2;
} else if (Sfile && (vt != VNON) && Lf->dev_def && (Lf->inp_ty == 1)) {
/*
* If the protocol name isn't known and this stream socket's vnode type
* isn't VNON, the stream socket will be handled mostly as a stream.
* Thus, a named file check is appropriate.
*/
if (is_file_named((char *)NULL, (vt == VCHR) ? 1 : 0))
Lf->sf |= SELNM;
}
/*
* Get IP structure.
*/
*Namech = '\0';
if (!ip || kread(ip, (char *)&ic, sizeof(ic))) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%scan't read IP control structure from %s",
sz ? " " : "", print_kptr(ip, (char *)NULL, 0));
enter_nm(Namech);
return;
}
if (!Lf->dev_def)
enter_dev_ch(print_kptr(ip, (char *)NULL, 0));
/*
* Check for protocol control block address. Enter if non-NULL and clear
* device definition flag.
*/
if (!pcb) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%ssocket stream has no TCP or UDP module",
sz ? " " : "");
enter_nm(Namech);
return;
}
/*
* Select processing by protocol name.
*/
if (pn && !strcmp(pn, "TCP")) {
/*
* Process TCP socket.
*/
if (kread(pcb, (char *)&tc, sizeof(tc))) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%scan't read TCP PCB from %s",
sz ? " " : "", print_kptr(pcb, (char *)NULL, 0));
enter_nm(Namech);
return;
}
/*
* Save TCP address.
*/
la = (unsigned char *)&ic.ipc_tcp_laddr;
pt = (u_short)ic.ipc_tcp_lport;
if (((struct in_addr *)la)->s_addr == INADDR_ANY && pt == 0) {
/*
* If the ipc_s structure has no local address, use the local
* address in its tcp_iph structure, and the port number in its
* tcph structure.
*/
la = (unsigned char *)&tc.tcp_u.tcp_u_iph.iph_src[0];
if (tc.tcp_hdr_len && tc.tcp_tcph
&& kread((KA_T)tc.tcp_tcph, (char *)&th, sizeof(th))
== 0)
pt = (u_short)th.th_lport;
}
lp = (int)ntohs(pt);
if ((int)ic.ipc_tcp_faddr != INADDR_ANY
|| (u_short)ic.ipc_tcp_fport != 0)
{
fa = (unsigned char *)&ic.ipc_tcp_faddr;
fp = (int)ntohs((u_short)ic.ipc_tcp_fport);
}
if (fa || la)
(void) ent_inaddr(la, lp, fa, fp, AF_INET);
/*
* Save TCP state and size information.
*/
Lf->lts.type = 0;
Lf->lts.state.i = (int)tc.tcp_state;
# if defined(HASTCPTPIQ) || defined(HASTCPTPIW)
# if defined(HASTCPTPIW)
Lf->lts.rw = (int)tc.tcp_rwnd;
Lf->lts.ww = (int)tc.tcp_swnd;
Lf->lts.rws = Lf->lts.wws = 1;
# endif /* defined(HASTCPTPIW) */
if ((rq = (int)tc.tcp_rnxt - (int)tc.tcp_rack - 1) < 0)
rq = 0;
if ((sq = (int)tc.tcp_snxt - (int)tc.tcp_suna - 1) < 0)
sq = 0;
# if defined(HASTCPTPIQ)
Lf->lts.rq = (unsigned long)rq;
Lf->lts.sq = (unsigned long)sq;
Lf->lts.rqs = Lf->lts.sqs = 1;
# endif /* defined(HASTCPTPIQ) */
if (Fsize) {
if (Lf->access == 'r')
Lf->sz = (SZOFFTYPE)rq;
else if (Lf->access == 'w')
Lf->sz = (SZOFFTYPE)sq;
else
Lf->sz = (SZOFFTYPE)(rq + sq);
Lf->sz_def = 1;
} else
Lf->off_def = 1;
# else /* !defined(HASTCPTPIQ) && !defined(HASTCPTPIW) */
if (!Fsize)
Lf->off_def = 1;
# endif /* defined(HASTCPTPIQ) || defined(HASTCPTPIW) */
# if defined(HASTCPOPT)
if (Ftcptpi & TCPTPI_FLAGS) {
/*
* Save TCP options and values..
*/
if (tc.tcp_naglim == (uint)1)
Lf->lts.topt |= TF_NODELAY;
Lf->lts.mss = (unsigned long)tc.tcp_mss;
Lf->lts.msss = (unsigned char)1;
}
# endif /* defined(HASTCPOPT) */
# if defined(HASSOOPT)
if (Ftcptpi & TCPTPI_FLAGS) {
/*
* Save socket options.
*/
if (tc.tcp_broadcast)
Lf->lts.opt |= SO_BROADCAST;
if (tc.tcp_so_debug)
Lf->lts.opt |= SO_DEBUG;
if (tc.tcp_dontroute)
Lf->lts.opt |= SO_DONTROUTE;
if (tc.tcp_keepalive_intrvl
&& (tc.tcp_keepalive_intrvl != 7200000)
) {
Lf->lts.opt |= SO_KEEPALIVE;
Lf->lts.kai = (unsigned int)tc.tcp_keepalive_intrvl;
}
if (tc.tcp_lingering) {
Lf->lts.opt |= SO_LINGER;
Lf->lts.ltm = (unsigned int)tc.tcp_linger;
}
if (tc.tcp_oobinline)
Lf->lts.opt |= SO_OOBINLINE;
if (tc.tcp_reuseaddr)
Lf->lts.opt |= SO_REUSEADDR;
if (tc.tcp_reuseport)
Lf->lts.opt |= SO_REUSEPORT;
if (tc.tcp_useloopback)
Lf->lts.opt |= SO_USELOOPBACK;
Lf->lts.qlen = (unsigned int)tc.tcp_conn_ind_cnt;
Lf->lts.qlim = (unsigned int)tc.tcp_conn_ind_max;
if (Lf->lts.qlen || Lf->lts.qlim)
Lf->lts.qlens = Lf->lts.qlims = (unsigned char)1;
}
# endif /* defined(HASSOOPT) */
Namech[0] = '\0';
return;
} else if (pn && !strcmp(pn, "UDP")) {
/*
* Process UDP socket.
*/
if (kread(pcb, (char *)&ud, sizeof(ud))) {
ep = endnm(&sz);
(void) snpf(ep, sz, "%scan't read UDP PCB from %s",
sz ? " " : "", print_kptr(pcb, (char *)NULL, 0));
enter_nm(Namech);
return;
}
/*
* Save UDP address and TPI state.
*/
la = (unsigned char *)&ic.ipc_udp_addr;
pt = (u_short)ic.ipc_udp_port;
if (((struct in_addr *)la)->s_addr == INADDR_ANY && pt == 0) {
/*
* If the ipc_s structure has no local address, use the one in the
* udp_s structure.
*/
pt = (u_short)ud.udp_port[0];
}
(void) ent_inaddr(la, (int)ntohs(pt), (unsigned char *)NULL,
-1, AF_INET);
if (!Fsize)
Lf->off_def = 1;
Lf->lts.type = 1;
Lf->lts.state.ui = (unsigned int)ud.udp_state;
Namech[0] = '\0';
return;
} else {
/*
* Record an unknown protocol.
*/
ep = endnm(&sz);
(void) snpf(ep, sz, "%sunknown stream protocol: %s",
sz ? " " : "", pn ? pn : "NUll");
}
if (Namech[0])
enter_nm(Namech);
}
#endif /* HPUXV>=1030 */