| /* |
| * dsock.c - Solaris 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.31 2011/08/07 22:53:42 abe Exp $"; |
| #endif |
| |
| |
| #include "lsof.h" |
| |
| #if solaris>=110000 |
| #include <inet/ipclassifier.h> |
| #endif /* solaris>=110000 */ |
| |
| |
| #if defined(HAS_LIBCTF) && solaris>=110000 |
| /* |
| * Icmp_t, rts_t and udp_t structure support for Solaris >=11 via libctf |
| * |
| * These structure definitions may look like kernel structures, but they |
| * are not. They have been defined to have member names that duplicate |
| * those used by the kernel that are of interest to lsof. Member valuess |
| * are obtained via the CTF library, libctf. |
| * |
| * Robert Byrnes developed the CTF library access code and contributed it |
| * to lsof. |
| */ |
| |
| /* |
| * Icmp_t internal structure definition |
| */ |
| |
| typedef struct icmp_s { |
| uint_t icmp_state; /* TPI state */ |
| KA_T *icmp_connp; /* connection structure pointer */ |
| in6_addr_t icmp_bound_v6src; /* Explicitely bound to address */ |
| in6_addr_t icmp_v6src; /* Source address of this stream */ |
| union { |
| uint_t icmp_dummy; |
| uint_t |
| icmp_Debug : 1, /* SO_DEBUG option */ |
| icmp_dontroute : 1, /* SO_DONTROUTE option */ |
| icmp_broadcast : 1, /* SO_BROADCAST option */ |
| icmp_reuseaddr : 1, /* SO_REUSEADDR option */ |
| icmp_useloopback : 1, /* SO_USELOOPBACK option */ |
| icmp_hdrincl : 1, /* IP_HDRINCL option, etc. */ |
| icmp_dgram_errind : 1, /* SO_DGRAM_ERRIND option */ |
| icmp_pad : 25; /* pad to bit 31 */ |
| } icmp_debug; /* This name identifies a single bit |
| * variable of the kernel's union, but |
| * CTF won't read individual bit |
| * variables, so for CTF's purposes |
| * it is declared as a uint_t union, |
| * named by the first bit variable of |
| * the kernel union, whose address CTF |
| * groks. */ |
| } icmp_t; |
| |
| |
| /* |
| * Rts_t internal structure definition |
| */ |
| |
| typedef struct rts_s { |
| uint_t rts_state; /* Provider interface state */ |
| |
| # if defined(HAS_CONN_NEW) |
| KA_T *rts_connp; /* connection structure pointer */ |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| union { |
| uint_t rts_dummy; |
| uint_t |
| rts_Debug : 1, /* SO_DEBUG option */ |
| rts_dontroute : 1, /* SO_DONTROUTE option */ |
| rts_broadcast : 1, /* SO_BROADCAST option */ |
| rts_reuseaddr : 1, /* SO_REUSEADDR option */ |
| rts_useloopback : 1, /* SO_USELOOPBACK option */ |
| icmp_pad : 27; /* padding to bit 31 */ |
| } rts_debug; /* This name identifies a single bit |
| * variable, but CTF won't read |
| * individual bit variables, so for |
| * CTF's purposes it is declared as a |
| * uint_t union, named by its first |
| * bit variable, whose address CTF |
| * groks. */ |
| } rts_t; |
| |
| /* |
| * Udp_t internal structure definition |
| */ |
| |
| typedef struct udp { uint_t udp_state; /* TPI state */ |
| in_port_t udp_port; /* port bound to this stream */ |
| in_port_t udp_dstport; /* connected port */ |
| in6_addr_t udp_v6src; /* source address of this stream */ |
| in6_addr_t udp_v6dst; /* connected destination */ |
| ushort_t udp_ipversion; /* version -- IPV[46]_VERSION */ |
| KA_T *udp_connp; /* connection structure pointer */ |
| uint_t udp_bits; /* socket option bits */ |
| } udp_t; |
| |
| |
| /* |
| * CTF definitions for icmp_t, rts_t and udp_t |
| */ |
| |
| static int IRU_ctfs = 0; /* CTF initialization status for |
| * icmp_t, rts_t and udp_t */ |
| |
| # if defined(_LP64) |
| #define IRU_MOD_FORMAT "/kernel/%s/genunix" |
| #else /* !defined(_LP64) */ |
| #define IRU_MOD_FORMAT "/kernel/genunix" |
| #endif /* defined(_LP64) */ |
| |
| /* genunix pathname template to which |
| * the kernel's instruction type set |
| * is added for CTF access to icmp_t, |
| * rts_t and udp_t */ |
| |
| |
| /* |
| * Icmp_t, rts_t and udp_t access definitions and structures |
| */ |
| |
| #define ICMP_T_TYPE_NAME "icmp_t" |
| |
| static CTF_member_t icmp_t_members[] = { |
| CTF_MEMBER(icmp_state), |
| #define MX_icmp_state 0 |
| |
| # if defined(HAS_CONN_NEW) |
| |
| CTF_MEMBER(icmp_connp), |
| #define MX_icmp_connp 1 |
| # else /* !defined(HAS_CONN_NEW) */ |
| CTF_MEMBER(icmp_bound_v6src), |
| #define MX_icmp_bound_v6src 1 |
| |
| CTF_MEMBER(icmp_v6src), |
| #define MX_icmp_v6src 2 |
| |
| CTF_MEMBER(icmp_debug), |
| #define MX_icmp_debug 3 |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| { NULL, 0 } |
| }; |
| |
| |
| #define RTS_T_TYPE_NAME "rts_t" |
| |
| static CTF_member_t rts_t_members[] = { |
| CTF_MEMBER(rts_state), |
| #define MX_rts_state 0 |
| |
| # if defined(HAS_CONN_NEW) |
| CTF_MEMBER(rts_connp), |
| #define MX_rts_connp 1 |
| # else /* !defined(HAS_CONN_NEW) */ |
| |
| CTF_MEMBER(rts_debug), |
| #define MX_rts_debug 1 |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| { NULL, 0 } |
| }; |
| |
| |
| #define UDP_T_TYPE_NAME "udp_t" |
| |
| static CTF_member_t udp_t_members[] = { |
| CTF_MEMBER(udp_state), |
| #define MX_udp_state 0 |
| |
| CTF_MEMBER(udp_connp), |
| #define MX_udp_connp 1 |
| |
| # if !defined(HAS_CONN_NEW) |
| CTF_MEMBER(udp_port), |
| #define MX_udp_port 2 |
| |
| CTF_MEMBER(udp_dstport), |
| #define MX_udp_dstport 3 |
| |
| CTF_MEMBER(udp_v6src), |
| #define MX_udp_v6src 4 |
| |
| CTF_MEMBER(udp_v6dst), |
| #define MX_udp_v6dst 5 |
| |
| CTF_MEMBER(udp_ipversion), |
| #define MX_udp_ipversion 6 |
| |
| CTF_MEMBER(udp_bits), |
| #define MX_udp_bits 7 |
| # endif /* !defined(HAS_CONN_NEW) */ |
| |
| { NULL, 0 } |
| }; |
| |
| |
| /* |
| * CTF icmp_t, rts_t and udp_t request table |
| */ |
| |
| static CTF_request_t IRU_requests[] = { |
| { ICMP_T_TYPE_NAME, icmp_t_members }, |
| { RTS_T_TYPE_NAME, rts_t_members }, |
| { UDP_T_TYPE_NAME, udp_t_members }, |
| { NULL, NULL } |
| }; |
| |
| |
| /* |
| * Icmp_t, rts_t and udp_t function prototypes |
| */ |
| |
| _PROTOTYPE(static int read_icmp_t,(KA_T va, KA_T ph, KA_T ia, icmp_t *ic)); |
| _PROTOTYPE(static int read_rts_t,(KA_T va, KA_T ph, KA_T ra, rts_t *rt)); |
| _PROTOTYPE(static int read_udp_t,(KA_T ua, udp_t *uc)); |
| #endif /* defined(HAS_LIBCTF) && solaris>=110000 */ |
| |
| |
| #if solaris<80000 || defined(HAS_IPCLASSIFIER_H) |
| /* |
| * Make sure the tcpb structure is always defined. |
| */ |
| |
| typedef struct tcpb { |
| int dummy; |
| } tcpb_t; |
| #endif /* solaris<80000 || defined(HAS_IPCLASSIFIER_H) */ |
| |
| #if defined(HASIPv6) |
| |
| /* |
| * IPv6_2_IPv4() -- macro to define the address of an IPv4 address contained |
| * in an IPv6 address |
| */ |
| |
| #define IPv6_2_IPv4(v6) (((uint8_t *)((struct in6_addr *)v6)->s6_addr)+12) |
| |
| /* |
| * IPv_ADDR_UNSPEC() -- macro to test an IP[46] address for an unspecified |
| * address value |
| */ |
| |
| #define IPv_ADDR_UNSPEC(af, p) \ |
| (((af) == AF_INET6) ? (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)p)) \ |
| : (((struct in_addr *)(p))->s_addr == INADDR_ANY)) |
| #else /* !defined(HASIPv6) */ |
| |
| /* |
| * IPv_ADDR_UNSPEC() -- IPv4-only form of macro to test for an unspecified |
| * address value |
| */ |
| |
| #define IPv_ADDR_UNSPEC(af, p) (((struct in_addr *)(p))->s_addr == INADDR_ANY) |
| |
| #endif /* !defined(HASIPv6) */ |
| |
| #if defined(HASTCPOPT) |
| # if solaris==20600 |
| #include <netinet/tcp.h> |
| # endif /* solaris==20600 */ |
| #include <netinet/tcp_timer.h> |
| #include <netinet/tcp_var.h> |
| |
| # if defined(TH_TIMER_NEEDED) |
| #define ACK_TIMER TH_TIMER_NEEDED |
| # else |
| # if defined(TH_ACK_TIMER_NEEDED) |
| #define ACK_TIMER TH_ACK_TIMER_NEEDED |
| # endif /* defined(TH_ACK_TIMER_NEEDED) */ |
| # endif /* defined(TH_TIMER_NEEDED */ |
| #endif /* defined(HASTCPOPT) */ |
| |
| #if defined(HASSOOPT) |
| # if solaris<100000 |
| #define KEEPALIVE_INTERVAL tcp_keepalive_intrvl |
| # else /* solaris>=100000 */ |
| #define KEEPALIVE_INTERVAL tcp_ka_last_intrvl |
| # endif /* solaris<100000 */ |
| #endif /* defined(HASSOOPT) */ |
| |
| |
| /* |
| * Local function prototypes |
| */ |
| |
| _PROTOTYPE(static void save_TCP_size,(tcp_t *tc)); |
| _PROTOTYPE(static void save_TCP_states,(tcp_t *tc, caddr_t *fa, tcpb_t *tb, |
| caddr_t *xp)); |
| |
| |
| /* |
| * build_IPstates() -- build the TCP and UDP state tables |
| */ |
| |
| void |
| build_IPstates() |
| { |
| if (!TcpSt) { |
| (void) enter_IPstate("TCP", "CLOSED", TCPS_CLOSED); |
| (void) enter_IPstate("TCP", "IDLE", TCPS_IDLE); |
| (void) enter_IPstate("TCP", "BOUND", TCPS_BOUND); |
| (void) enter_IPstate("TCP", "LISTEN", TCPS_LISTEN); |
| (void) enter_IPstate("TCP", "SYN_SENT", TCPS_SYN_SENT); |
| (void) enter_IPstate("TCP", "SYN_RCVD", TCPS_SYN_RCVD); |
| (void) enter_IPstate("TCP", "ESTABLISHED", TCPS_ESTABLISHED); |
| (void) enter_IPstate("TCP", "CLOSE_WAIT", TCPS_CLOSE_WAIT); |
| (void) enter_IPstate("TCP", "FIN_WAIT_1", TCPS_FIN_WAIT_1); |
| (void) enter_IPstate("TCP", "CLOSING", TCPS_CLOSING); |
| (void) enter_IPstate("TCP", "LAST_ACK", TCPS_LAST_ACK); |
| (void) enter_IPstate("TCP", "FIN_WAIT_2", TCPS_FIN_WAIT_2); |
| (void) enter_IPstate("TCP", "TIME_WAIT", TCPS_TIME_WAIT); |
| (void) enter_IPstate("TCP", (char *)NULL, 0); |
| } |
| if (!UdpSt) { |
| (void) enter_IPstate("UDP", "Unbound", TS_UNBND); |
| (void) enter_IPstate("UDP", "Wait_BIND_REQ_Ack", TS_WACK_BREQ); |
| (void) enter_IPstate("UDP", "Wait_UNBIND_REQ_Ack", TS_WACK_UREQ); |
| (void) enter_IPstate("UDP", "Idle", TS_IDLE); |
| (void) enter_IPstate("UDP", "Wait_OPT_REQ_Ack", TS_WACK_OPTREQ); |
| (void) enter_IPstate("UDP", "Wait_CONN_REQ_Ack", TS_WACK_CREQ); |
| (void) enter_IPstate("UDP", "Wait_CONN_REQ_Confirm", TS_WCON_CREQ); |
| (void) enter_IPstate("UDP", "Wait_CONN_IND_Response", TS_WRES_CIND); |
| (void) enter_IPstate("UDP", "Wait_CONN_RES_Ack", TS_WACK_CRES); |
| (void) enter_IPstate("UDP", "Wait_Data_Xfr", TS_DATA_XFER); |
| (void) enter_IPstate("UDP", "Wait_Read_Release", TS_WIND_ORDREL); |
| (void) enter_IPstate("UDP", "Wait_Write_Release", TS_WREQ_ORDREL); |
| (void) enter_IPstate("UDP", "Wait_DISCON_REQ_Ack", TS_WACK_DREQ6); |
| (void) enter_IPstate("UDP", "Wait_DISCON_REQ_Ack", TS_WACK_DREQ7); |
| (void) enter_IPstate("UDP", "Wait_DISCON_REQ_Ack", TS_WACK_DREQ9); |
| (void) enter_IPstate("UDP", "Wait_DISCON_REQ_Ack", TS_WACK_DREQ10); |
| (void) enter_IPstate("UDP", "Wait_DISCON_REQ_Ack", TS_WACK_DREQ11); |
| (void) enter_IPstate("UDP", (char *)NULL, 0); |
| } |
| } |
| |
| |
| /* |
| * print_tcptpi() - print TCP/TPI info |
| */ |
| |
| void |
| print_tcptpi(nl) |
| int nl; /* 1 == '\n' required */ |
| { |
| char *cp = (char *)NULL; |
| char sbuf[128]; |
| int i; |
| int ps = 0; |
| unsigned int u; |
| |
| if (Ftcptpi & TCPTPI_STATE) { |
| switch (Lf->lts.type) { |
| case 0: /* TCP */ |
| if (!TcpSt) |
| (void) build_IPstates(); |
| if ((i = Lf->lts.state.i + TcpStOff) < 0 || i >= TcpNstates) { |
| (void) snpf(sbuf, sizeof(sbuf), "UNKNOWN_TCP_STATE_%d", |
| Lf->lts.state.i); |
| cp = sbuf; |
| } else |
| cp = TcpSt[i]; |
| break; |
| case 1: /* TPI */ |
| if (!UdpSt) |
| (void) build_IPstates(); |
| if ((u = Lf->lts.state.ui + UdpStOff) < 0 || u >= UdpNstates) { |
| (void) snpf(sbuf, sizeof(sbuf), "UNKNOWN_UDP_STATE_%u", |
| Lf->lts.state.ui); |
| cp = sbuf; |
| } else |
| cp = UdpSt[u]; |
| } |
| if (cp) { |
| 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.pqlens || 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_DGRAM_ERRIND) |
| if (opt & SO_DGRAM_ERRIND) { |
| (void) printf("%cDGRAM_ERRIND", sep); |
| opt &= ~SO_DGRAM_ERRIND; |
| sep = ','; |
| } |
| # endif /* defined(SO_DGRAM_ERRIND) */ |
| |
| # 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.pqlens) { |
| (void) printf("%cPQLEN=%u", sep, Lf->lts.pqlen); |
| sep = ','; |
| } |
| 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 (Lf->lts.rbszs) { |
| (void) printf("%cRCVBUF=%lu", sep, Lf->lts.rbsz); |
| sep = ','; |
| } |
| |
| # if defined(SO_REUSEADDR) |
| if (opt & SO_REUSEADDR) { |
| (void) printf("%cREUSEADDR", sep); |
| opt &= ~SO_REUSEADDR; |
| sep = ','; |
| } |
| # endif /* defined(SO_REUSEADDR) */ |
| |
| if (Lf->lts.sbszs) { |
| (void) printf("%cSNDBUF=%lu", sep, Lf->lts.sbsz); |
| sep = ','; |
| } |
| |
| # if defined(SO_TIMESTAMP) |
| if (opt & SO_TIMESTAMP) { |
| (void) printf("%cTIMESTAMP", sep); |
| opt &= ~SO_TIMESTAMP; |
| sep = ','; |
| } |
| # endif /* defined(SO_TIMESTAMP) */ |
| |
| # 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 defined(TF_ACKNOW) |
| if (topt & TF_ACKNOW) { |
| (void) printf("%cACKNOW", sep); |
| topt &= ~TF_ACKNOW; |
| sep = ','; |
| } |
| # endif /* defined(TF_ACKNOW) */ |
| |
| # if defined(TF_DELACK) |
| if (topt & TF_DELACK) { |
| (void) printf("%cDELACK", sep); |
| topt &= ~TF_DELACK; |
| sep = ','; |
| } |
| # endif /* defined(TF_DELACK) */ |
| |
| 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 defined(TF_NOOPT) |
| if (topt & TF_NOOPT) { |
| (void) printf("%cNOOPT", sep); |
| topt &= ~TF_NOOPT; |
| sep = ','; |
| } |
| # endif /* defined(TF_NOOPT) */ |
| |
| # if defined(TF_SENTFIN) |
| if (topt & TF_SENTFIN) { |
| (void) printf("%cSENTFIN", sep); |
| topt &= ~TF_SENTFIN; |
| sep = ','; |
| } |
| # endif /* defined(TF_SENTFIN) */ |
| |
| 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'); |
| } |
| |
| #if solaris>=110000 |
| /* |
| * procss_VSOCK() -- process a VSOCK socket |
| */ |
| |
| # if defined(HAS_CONN_NEW) |
| /* |
| * Adjust for changes in the conn_s structure, introduced at OpenSolaris |
| * level b134. |
| */ |
| |
| #define conn_ulp conn_proto |
| #define conn_rem V4_PART_OF_V6(connua_v6addr.connua_faddr) |
| #define conn_src V4_PART_OF_V6(connua_v6addr.connua_laddr) |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| int |
| process_VSOCK(va, v, so) |
| KA_T va; /* containing vnode address */ |
| struct vnode *v; /* pointer to containing vnode */ |
| struct sonode *so; /* pointer to socket's sonode */ |
| { |
| int af; /* address family */ |
| struct conn_s cs; /* connection info */ |
| unsigned char *fa = (unsigned char *)NULL; |
| /* foreign address */ |
| u_short fp = (u_short)0; /* foreign port */ |
| u_short lp; /* local port */ |
| icmp_t ic; /* ICMP control structure */ |
| KA_T ka; /* temporary kernel address */ |
| unsigned char *la = (unsigned char *)NULL; |
| /* local address */ |
| KA_T pha; /* protocol handle address */ |
| rts_t rt; /* AF_ROUTE control structure */ |
| int s; /* state */ |
| unsigned char *ta = (unsigned char *)NULL; |
| /* temporary address */ |
| char tbuf[32], tbuf1[32]; /* temporary buffers */ |
| tcp_t tc; /* TCP control structure */ |
| tcph_t th; /* TCP header structure */ |
| |
| # if defined(HAS_CONN_NEW) |
| struct ip_xmit_attr_s xa; |
| caddr_t *xp = (caddr_t *)NULL; |
| # else /* !defined(HAS_CONN_NEW) */ |
| tcph_t *tha = (tcph_t *)NULL; /* TCP header structure address */ |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| char *ty; /* TCP type */ |
| udp_t uc; /* local UDP control structure */ |
| /* |
| * Read VSOCK's connection information. Enter its address as the protocol |
| * control block device address. |
| */ |
| if (!(pha = (KA_T)so->so_proto_handle)) |
| return(0); |
| if (kread(pha, (char *)&cs, sizeof(cs))) { |
| (void) snpf(Namech, Namechl, |
| "vnode at %s; snode at %s; can't read proto handle at: %s", |
| print_kptr(va, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v->v_data, tbuf1, sizeof(tbuf1)), |
| print_kptr(pha, (char *)NULL, 0)); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| enter_dev_ch(print_kptr(pha, (char *)NULL, 0)); |
| /* |
| * Process connection info by protocol. |
| */ |
| switch ((af = so->so_family)) { |
| case AF_INET: |
| case AF_INET6: |
| |
| /* |
| * Set INET type -- IPv4 or IPv6. |
| */ |
| if (af == AF_INET) |
| ty = "IPv4"; |
| else |
| ty = "IPv6"; |
| (void) snpf(Lf->type, sizeof(Lf->type), ty); |
| |
| switch (cs.conn_ulp) { |
| case IPPROTO_TCP: |
| |
| /* |
| * Process TCP socket; read its control structure. |
| */ |
| if (!(ka = (KA_T)cs.conn_proto_priv.cp_tcp) |
| || kread(ka, (char *)&tc, sizeof(tc)) |
| ) { |
| (void) snpf(Namech, Namechl - 1, |
| "can't read TCP socket's control structure: %s", |
| print_kptr((KA_T)ka, (char *)NULL, 0)); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| /* |
| * Set TCP protcol name in Lf->iproto[]. |
| */ |
| (void) snpf(Lf->iproto, IPROTOL - 1, "%s", "TCP"); |
| Lf->iproto[IPROTOL - 1] = '\0'; |
| Lf->inp_ty = 2; |
| /* |
| * Check for TCP state inclusion or exclusion. |
| */ |
| if (TcpNstates) { |
| if ((s = (int)tc.tcp_state + TcpStOff) < TcpNstates) { |
| if (TcpStXn) { |
| if (TcpStX[s]) { |
| Lf->sf |= SELEXCLF; |
| return(1); |
| } |
| } |
| if (TcpStIn) { |
| if (TcpStI[s]) { |
| TcpStI[s] = 2; |
| Lf->sf |= SELNET; |
| } else { |
| Lf->sf |= SELEXCLF; |
| return(1); |
| } |
| } |
| } |
| } |
| /* |
| * Set network file selection status. |
| */ |
| if (Fnet) { |
| if (!FnetTy |
| || ((FnetTy == 4) && (af == AF_INET)) |
| || ((FnetTy == 6) && (af == AF_INET6)) |
| ) { |
| Lf->sf |= SELNET; |
| } |
| } |
| /* |
| * Save local and remote (foreign) TCP address. |
| */ |
| if (af == AF_INET6) { |
| ta = (unsigned char *)&cs.connua_v6addr.connua_faddr; |
| la = (unsigned char *)&cs.connua_v6addr.connua_laddr; |
| } else { |
| ta = (unsigned char *)&cs.conn_rem; |
| la = (unsigned char *)&cs.conn_src; |
| } |
| if (!IPv_ADDR_UNSPEC(af, ta) || (u_short)cs.conn_fport) { |
| fa = ta; |
| fp = (u_short)cs.conn_fport; |
| } |
| if ((af == AF_INET6) |
| && ((la && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)la)) |
| || ((fa && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)fa)))) |
| ) { |
| |
| /* |
| * Convert IPv4 addresses in IPv6 structures to IPv4 addresses |
| * in IPv4 structures. Change the address family to AF_INET. |
| */ |
| if (la) |
| la = (unsigned char *)IPv6_2_IPv4(la); |
| if (fa) |
| fa = (unsigned char *)IPv6_2_IPv4(fa); |
| af = AF_INET; |
| } |
| lp = (u_short)cs.conn_lport; |
| (void) ent_inaddr(la, (int)ntohs(lp), fa, (int)ntohs(fp), af); |
| /* |
| * Save TCP state information. |
| */ |
| |
| # if defined(HAS_CONN_NEW) |
| if ((ka = (KA_T)cs.conn_ixa) |
| && !kread(ka, (char *)&xa, sizeof(xa)) |
| ) { |
| xp = (caddr_t *)&xa; |
| } |
| (void) save_TCP_states(&tc, (caddr_t *)&cs, (tcpb_t *)NULL, xp); |
| # else /* !defined(HAS_CONN_NEW) */ |
| if (tc.tcp_tcp_hdr_len |
| && (ka = (KA_T)tc.tcp_tcph) |
| && !kread(ka, (char *)&th, sizeof(th)) |
| ) { |
| tha = &th; |
| } |
| (void) save_TCP_states(&tc, (caddr_t *)tha, (tcpb_t *)NULL, |
| (caddr_t *)NULL); |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| Lf->lts.type = 0; |
| Lf->lts.state.i = (int)tc.tcp_state; |
| /* |
| * Save TCP size information. |
| */ |
| (void) save_TCP_size(&tc); |
| break; |
| case IPPROTO_UDP: |
| |
| /* |
| * Process UDP socket; read its control structure. |
| */ |
| if (!(ka = (KA_T)cs.conn_proto_priv.cp_udp) |
| || kread(ka, (char *)&uc, sizeof(uc)) |
| ) { |
| (void) snpf(Namech, Namechl - 1, |
| "can't read UDP socket's control structure: %s", |
| print_kptr((KA_T)ka, (char *)NULL, 0)); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| /* |
| * Set UDP protcol name in Lf->iproto[]. |
| */ |
| (void) snpf(Lf->iproto, IPROTOL - 1, "%s", "UDP"); |
| Lf->iproto[IPROTOL - 1] = '\0'; |
| Lf->inp_ty = 2; |
| /* |
| * Check for UDP state inclusion or exclusion. |
| */ |
| if (UdpNstates) { |
| if ((s = (int)uc.udp_state + TcpStOff) < UdpNstates) { |
| if (UdpStXn) { |
| if (UdpStX[s]) { |
| Lf->sf |= SELEXCLF; |
| return(1); |
| } |
| } |
| if (UdpStIn) { |
| if (UdpStI[s]) { |
| UdpStI[s] = 2; |
| Lf->sf |= SELNET; |
| } else { |
| Lf->sf |= SELEXCLF; |
| return(1); |
| } |
| } |
| } |
| } |
| /* |
| * Set network file selection status. |
| */ |
| if (Fnet) { |
| if (!FnetTy |
| || ((FnetTy == 4) && (af == AF_INET)) |
| || ((FnetTy == 6) && (af == AF_INET6)) |
| ) { |
| Lf->sf |= SELNET; |
| } |
| } |
| /* |
| * Save local and remote (foreign) UDP address. |
| */ |
| if (af == AF_INET6) { |
| ta = (unsigned char *)&cs.connua_v6addr.connua_faddr; |
| la = (unsigned char *)&cs.connua_v6addr.connua_laddr; |
| } else { |
| ta = (unsigned char *)&cs.conn_rem; |
| la = (unsigned char *)&cs.conn_src; |
| } |
| if (!IPv_ADDR_UNSPEC(af, ta) || (u_short)cs.conn_fport) { |
| fa = ta; |
| fp = (u_short)cs.conn_fport; |
| } |
| lp = (u_short)cs.conn_lport; |
| (void) ent_inaddr(la, (int)ntohs(lp), fa, (int)ntohs(fp), af); |
| /* |
| * Save UDP state and size information. |
| */ |
| if (!Fsize) |
| Lf->off_def = 1; |
| Lf->lts.type = 1; |
| Lf->lts.state.ui = (unsigned int)uc.udp_state; |
| |
| # if defined(HASSOOPT) |
| /* |
| * Save UDP flags. |
| */ |
| if (Ftcptpi & TCPTPI_FLAGS) { |
| union { |
| uint_t flags; |
| uint_t |
| udpb_debug : 1, /* SO_DEBUG option */ |
| udpb_dontroute : 1, /* SO_DONTROUTE option */ |
| udpb_broadcast : 1, /* SO_BROADCAST option */ |
| udpb_reuseaddr : 1, /* SO_REUSEADDR option */ |
| udpb_useloopback : 1, /* SO_USELOOPBACK option */ |
| udpb_dgram_errind : 1, /* SO_DGRAM_ERRIND option */ |
| udpb_pad : 26; /* pad to bit 31 */ |
| } ucf; |
| |
| ucf.flags = uc.udp_bits; |
| if (ucf.udpb_debug) |
| Lf->lts.opt |= SO_DEBUG; |
| if (ucf.udpb_dontroute) |
| Lf->lts.opt |= SO_DONTROUTE; |
| if (ucf.udpb_broadcast) |
| Lf->lts.opt |= SO_BROADCAST; |
| if (ucf.udpb_reuseaddr) |
| Lf->lts.opt |= SO_REUSEADDR; |
| if (ucf.udpb_useloopback) |
| Lf->lts.opt |= SO_USELOOPBACK; |
| if (ucf.udpb_dgram_errind) |
| Lf->lts.opt |= SO_DGRAM_ERRIND; |
| } |
| # endif /* defined(HASSOOPT) */ |
| |
| break; |
| case IPPROTO_ICMP: |
| case IPPROTO_ICMPV6: |
| |
| /* |
| * Process ICMP or ICMP6 socket. |
| * |
| * Set protocol name. |
| */ |
| if (cs.conn_ulp == IPPROTO_ICMP) |
| ty = "ICMP"; |
| else |
| ty = "ICMP6"; |
| (void) snpf(Lf->iproto, IPROTOL - 1, "%s", ty); |
| Lf->iproto[IPROTOL - 1] = '\0'; |
| Lf->inp_ty = 2; |
| /* |
| * Read the ICMP control structure. |
| */ |
| if (read_icmp_t(va, pha, (KA_T)cs.conn_proto_priv.cp_icmp, &ic)) |
| return(1); |
| /* |
| * Save ICMP size and state information. |
| */ |
| if (!Fsize) |
| Lf->off_def = 1; |
| Lf->lts.type = 1; |
| Lf->lts.state.ui = (unsigned int)ic.icmp_state; |
| /* |
| * Set network file selection status. |
| */ |
| if (Fnet) { |
| if (!FnetTy |
| || ((FnetTy == 4) && (af == AF_INET)) |
| || ((FnetTy == 6) && (af == AF_INET6)) |
| ) { |
| Lf->sf |= SELNET; |
| } |
| } |
| /* |
| * Save addresses. |
| */ |
| ta = (af == AF_INET6) ? (unsigned char *)&ic.icmp_bound_v6src |
| : (unsigned char *)&V4_PART_OF_V6(ic.icmp_bound_v6src); |
| if (!IPv_ADDR_UNSPEC(af, ta)) |
| la = ta; |
| ta = (af == AF_INET6) ? (unsigned char *)&ic.icmp_v6src |
| : (unsigned char *)&V4_PART_OF_V6(ic.icmp_v6src); |
| if (!IPv_ADDR_UNSPEC(af, ta)) |
| fa = ta; |
| if (la || fa) |
| (void)ent_inaddr(la, 0, fa, 0, af); |
| |
| # if defined(HASSOOPT) |
| /* |
| * Save ICMP flags. |
| */ |
| if (Ftcptpi & TCPTPI_FLAGS) { |
| if (ic.icmp_debug.icmp_Debug) |
| Lf->lts.opt |= SO_DEBUG; |
| if (ic.icmp_debug.icmp_dontroute) |
| Lf->lts.opt |= SO_DONTROUTE; |
| if (ic.icmp_debug.icmp_broadcast) |
| Lf->lts.opt |= SO_BROADCAST; |
| if (ic.icmp_debug.icmp_reuseaddr) |
| Lf->lts.opt |= SO_REUSEADDR; |
| if (ic.icmp_debug.icmp_useloopback) |
| Lf->lts.opt |= SO_USELOOPBACK; |
| if (ic.icmp_debug.icmp_dgram_errind) |
| Lf->lts.opt |= SO_DGRAM_ERRIND; |
| } |
| # endif /* defined(HASSOOPT) */ |
| |
| break; |
| default: |
| (void) snpf(Namech, Namechl - 1, |
| "unsupported conn_s AF_INET%s protocol: %u", |
| (af == AF_INET6) ? "6" : "", |
| (unsigned int)cs.conn_ulp); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| break; |
| case AF_ROUTE: |
| |
| /* |
| * Set INET type -- IPv4 or IPv6. |
| */ |
| if (af == AF_INET) |
| ty = "IPv4"; |
| else |
| ty = "IPv6"; |
| (void) snpf(Lf->type, sizeof(Lf->type), ty); |
| /* |
| * Set protocol name. |
| */ |
| (void) strncpy(Lf->iproto, "ROUTE", IPROTOL - 1); |
| Lf->iproto[IPROTOL - 1] = '\0'; |
| Lf->inp_ty = 2; |
| |
| /* |
| * Read routing control structure. |
| */ |
| if (read_rts_t(va, pha, (KA_T)cs.conn_proto_priv.cp_rts, &rt)) |
| return(1); |
| /* |
| /* |
| * Save AF_ROUTE size and state information. |
| */ |
| if (!Fsize) |
| Lf->off_def = 1; |
| Lf->lts.type = 1; |
| Lf->lts.state.i = (int)rt.rts_state; |
| /* |
| * Set network file selection status. |
| */ |
| if (Fnet) { |
| if (!FnetTy |
| || ((FnetTy == 4) && (af == AF_INET)) |
| || ((FnetTy == 6) && (af == AF_INET6)) |
| ) { |
| Lf->sf |= SELNET; |
| } |
| } |
| |
| # if defined(HASSOOPT) |
| /* |
| * Save ROUTE flags. |
| */ |
| if (Ftcptpi & TCPTPI_FLAGS) { |
| if (rt.rts_debug.rts_Debug) |
| Lf->lts.opt |= SO_DEBUG; |
| if (rt.rts_debug.rts_dontroute) |
| Lf->lts.opt |= SO_DONTROUTE; |
| if (rt.rts_debug.rts_broadcast) |
| Lf->lts.opt |= SO_BROADCAST; |
| if (rt.rts_debug.rts_reuseaddr) |
| Lf->lts.opt |= SO_REUSEADDR; |
| if (rt.rts_debug.rts_useloopback) |
| Lf->lts.opt |= SO_USELOOPBACK; |
| } |
| # endif /* defined(HASSOOPT) */ |
| |
| break; |
| default: |
| (void) printiproto((int)cs.conn_ulp); |
| (void) snpf(Namech, Namechl - 1, "unsupported socket family: %u", |
| so->so_family); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| Lf->inp_ty = 2; |
| } |
| return(1); |
| } |
| #endif /* solaris>=110000*/ |
| |
| |
| /* |
| * process_socket() - process Solaris socket |
| */ |
| |
| void |
| process_socket(sa, ty) |
| KA_T sa; /* stream's data address in kernel */ |
| char *ty; /* socket type name */ |
| { |
| int af; |
| unsigned char *fa = (unsigned char *)NULL; |
| int fp = 0; |
| int i, lp; |
| |
| #if solaris<110000 |
| # if solaris>=100000 && defined(HAS_IPCLASSIFIER_H) |
| struct conn_s ic; |
| #define ipc_v6laddr conn_srcv6 |
| #define ipc_v6faddr conn_remv6 |
| #define ipc_fport conn_fport |
| #define ipc_lport conn_lport |
| # else /* solaris<100000 || !defined(HAS_IPCLASSIFIER_H) */ |
| struct ipc_s ic; |
| # endif /* solaris>=100000 && defined(HAS_IPCLASSIFIER_H) */ |
| #else /* solaris>=110000 */ |
| struct conn_s cs; |
| #endif /* solaris<110000 */ |
| |
| int ics = 0; |
| unsigned char *la = (unsigned char *)NULL; |
| struct module_info mi; |
| KA_T ka; |
| u_short p; |
| KA_T pcb = (KA_T)NULL; |
| struct queue q; |
| struct qinit qi; |
| KA_T qp; |
| u_short *s; |
| struct stdata sd; |
| unsigned char *ta; |
| char tbuf[32]; |
| |
| #if solaris<20600 |
| struct tcp_s { /* should come from kernel source |
| * file ../uts/common/inet/tcp.c */ |
| |
| # if solaris>=20400 |
| struct tcp_s *d1[8]; |
| # endif /* solaris>=20400 */ |
| |
| # if defined(P101318) && P101318>=32 |
| struct tcp_s *d1[6]; |
| # endif /* defined(P101318) && P101318>=32 */ |
| |
| int tcp_state; |
| queue_t *d3[2]; |
| mblk_t *d4[2]; |
| u_long d5; |
| mblk_t *d6; |
| u_long d7; |
| u_long tcp_snxt; /* Senders next seq num */ |
| u_long tcp_suna; /* Sender unacknowledged */ |
| u_long tcp_swnd; /* Senders window (relative to suna) */ |
| u_long d8[5]; |
| int tcp_hdr_len; /* combined TCP/IP header length */ |
| tcph_t *tcp_tcph; /* pointer to combined header */ |
| int d9; |
| unsigned int d10; |
| int d11; |
| mblk_t *d12; |
| long d13; |
| mblk_t *d14; |
| u_long d15; |
| |
| # if solaris<20400 && (!defined(P101318) || P101318<32) |
| mblk_t *d16; |
| # endif /* solaris<20400 && (!defined(P101318) || P101318<32) */ |
| |
| unsigned int d17; |
| u_long tcp_rnxt; /* Seq we expect to recv next */ |
| u_long tcp_rwnd; /* Current receive window */ |
| u_long d18; |
| long d19[2]; |
| mblk_t *d20[4]; |
| u_long d21[5]; |
| long d22[3]; |
| |
| # if solaris<20500 |
| u_long d23[2]; |
| u_long tcp_rack; /* Seq # we have acked */ |
| # else /* solaris>=20500 */ |
| u_long d23[3]; |
| # endif /* solaris<20500 */ |
| |
| # if solaris<20400 |
| u_long d24[28]; |
| # else /* solaris>=20400 */ |
| # if solaris<20500 |
| u_long d24[67]; |
| # else /* solaris>=20500 */ |
| # if solaris<20501 |
| u_long d25[6]; |
| # else /* solaris>=20501 */ |
| u_long d25[8]; |
| # endif /* solaris<20501 */ |
| u_long tcp_rack; /* Seq # we have acked */ |
| # if solaris<20501 |
| u_long d26[29]; |
| # else /* solaris>=20501 */ |
| u_long d26[33]; |
| # endif /* solaris>=20501 */ |
| # endif /* solaris<20500 */ |
| # endif /* solaris<20400 */ |
| |
| iph_t tcp_iph; |
| } tc; |
| #else /* solaris>=20600 */ |
| struct tcp_s tc; |
| #endif /* solaris<20600 */ |
| |
| #if solaris>=80000 && !defined(HAS_IPCLASSIFIER_H) |
| tcpb_t tcb; |
| #endif /* solaris>=80000 && !defined(HAS_IPCLASSIFIER_H) */ |
| |
| tcpb_t *tcbp = (tcpb_t *)NULL; |
| int tcs = 0; |
| tcph_t th; |
| tcph_t *tha = (tcph_t *)NULL; |
| |
| #if solaris<110000 |
| struct ud_s { /* should come from kernel source |
| * file ../uts/common/inet/udp.c */ |
| uint udp_state; /* TPI state */ |
| unsigned char d1[2]; |
| unsigned char udp_port[2]; /* port bound to this stream */ |
| unsigned char udp_src[4]; /* source address of this stream */ |
| } uc; |
| #else /* solaris>=110000 */ |
| udp_t uc; /* UDP control structure */ |
| #endif /* solaris<110000 */ |
| int ucs = 0; |
| |
| #if defined(HASIPv6) |
| if (strrchr(ty, '6')) { |
| (void) snpf(Lf->type, sizeof(Lf->type), "IPv6"); |
| af = AF_INET6; |
| } else { |
| (void) snpf(Lf->type, sizeof(Lf->type), "IPv4"); |
| af = AF_INET; |
| } |
| #else /* !defined(HASIPv6) */ |
| (void) snpf(Lf->type, sizeof(Lf->type), "inet"); |
| af = AF_INET; |
| #endif /* defined(HASIPv6) */ |
| |
| /* |
| * Set network file selection status. |
| */ |
| if (Fnet) { |
| if (!FnetTy |
| || ((FnetTy == 4) && (af == AF_INET)) |
| |
| #if defined(HASIPv6) |
| || ((FnetTy == 6) && (af == AF_INET6)) |
| #endif /* defined(HASIPv6) */ |
| |
| ) { |
| if (!TcpStIn && !UdpStIn) |
| Lf->sf |= SELNET; |
| } |
| } |
| Lf->inp_ty = 2; |
| /* |
| * Convert type to upper case protocol name. |
| */ |
| if (ty) { |
| for (i = 0; (ty[i] != '\0') && (i < IPROTOL) && (i < 3); i++) { |
| if (islower((unsigned char)ty[i])) |
| Lf->iproto[i] = toupper((unsigned char)ty[i]); |
| else |
| Lf->iproto[i] = ty[i]; |
| } |
| } else |
| i = 0; |
| Lf->iproto[i] = '\0'; |
| /* |
| * Read stream queue entries to obtain private IP, TCP, and UDP structures. |
| */ |
| if (!sa || readstdata(sa, &sd)) |
| qp = (KA_T)NULL; |
| else |
| qp = (KA_T)sd.sd_wrq; |
| for (i = 0; qp && i < 20; i++, qp = (KA_T)q.q_next) { |
| if (kread(qp, (char *)&q, sizeof(q))) |
| break; |
| if ((ka = (KA_T)q.q_qinfo) == (KA_T)NULL |
| || kread(ka, (char *)&qi, sizeof(qi))) |
| continue; |
| if ((ka = (KA_T)qi.qi_minfo) == (KA_T)NULL |
| || kread(ka, (char *)&mi, sizeof(mi)) |
| || (ka = (KA_T)mi.mi_idname) == (KA_T)NULL) |
| continue; |
| if (kread(ka, (char *)&tbuf, sizeof(tbuf) - 1)) |
| continue; |
| if ((pcb = (KA_T)q.q_ptr) == (KA_T)NULL) |
| continue; |
| |
| #if solaris<110000 |
| if (strncasecmp(tbuf, "IP", 2) == 0) { |
| if (kread(pcb, (char *)&ic, sizeof(ic)) == 0) |
| ics = 1; |
| continue; |
| } |
| #endif /* solaris<110000 */ |
| |
| if (strncasecmp(tbuf, "TCP", 3) == 0) { |
| |
| #if solaris<=90000 || !defined(HAS_IPCLASSIFIER_H) |
| if (!kread((KA_T)pcb, (char *)&tc, sizeof(tc))) |
| |
| # if solaris>=80000 |
| { |
| if (tc.tcp_base |
| && !kread((KA_T)tc.tcp_base, (char *)&tcb, sizeof(tcb))) { |
| tcs = 1; |
| tcbp = &tcb; |
| } |
| tc.tcp_base = &tcb; /* support for macros */ |
| tcb.tcpb_tcp = &tc; /* support for macros */ |
| } |
| # else /* solaris<80000 */ |
| tcs = 1; |
| # endif /* solaris>=80000 */ |
| #else /* solaris>90000 && defined(HAS_IPCLASSIFIER_H) */ |
| # if solaris>=110000 |
| if (!kread(pcb, (char *)&cs, sizeof(cs)) |
| && (cs.conn_ulp == IPPROTO_TCP) |
| ) { |
| ics = 1; |
| if ((ka = (KA_T)cs.conn_proto_priv.cp_tcp) |
| && !kread(ka, (char *)&tc, sizeof(tc)) |
| ) { |
| tcs = 1; |
| } |
| } |
| # else /* solaris<110000 */ |
| if (!kread((KA_T)pcb, (char *)&ic, sizeof(ic)) |
| && ic.conn_tcp |
| && !kread((KA_T)ic.conn_tcp, (char *)&tc, sizeof(tc)) |
| ) { |
| ics = tcs = 1; |
| } |
| # endif /* solaris>=110000 */ |
| #endif /* solaris<=90000 || !defined(HAS_IPCLASSIFIER_H) */ |
| |
| if (tcs && TcpNstates) { |
| int s = (int)tc.tcp_state + TcpStOff; |
| /* |
| * Check for TCP state inclusion or exclusion. |
| */ |
| |
| if (s < TcpNstates) { |
| if (TcpStXn) { |
| if (TcpStX[s]) { |
| Lf->sf &= ~SELNET; |
| Lf->sf |= SELEXCLF; |
| return; |
| } |
| } |
| if (TcpStIn) { |
| if (TcpStI[s]) { |
| TcpStI[s] = 2; |
| Lf->sf |= SELNET; |
| } else { |
| Lf->sf &= ~SELNET; |
| Lf->sf |= SELEXCLF; |
| return; |
| } |
| } |
| } |
| } |
| if (!(Lf->sf & SELNET) && !TcpStIn && UdpStIn) { |
| if (Fnet) { |
| if (!FnetTy |
| || (FnetTy == 4) && (af == AF_INET) |
| |
| #if defined(HASIPv6) |
| || (FnetTy == 6) && (af == AF_INET6) |
| #endif /* defined(HASIPv6) */ |
| |
| ) { |
| Lf->sf |= SELNET; |
| } |
| } |
| } |
| continue; |
| } |
| if (strncasecmp(tbuf, "UDP", 3) == 0) { |
| |
| #if solaris<110000 |
| if (kread(pcb, (char *)&uc, sizeof(uc)) == 0) |
| ucs = 1; |
| #else /* solaris>=110000 */ |
| if (!kread(pcb, (char *)&cs, sizeof(cs)) |
| && (cs.conn_ulp == IPPROTO_UDP) |
| ) { |
| ics = 1; |
| if ((ka = (KA_T)cs.conn_proto_priv.cp_udp) |
| && !read_udp_t(ka, &uc) |
| ) { |
| ucs = 1; |
| } |
| } |
| #endif /* solaris<110000 */ |
| |
| if (ucs && UdpNstates) { |
| unsigned int s = (unsigned int)uc.udp_state + UdpStOff; |
| /* |
| * Check for UDP state inclusion or exclusion. |
| */ |
| |
| if (s < UdpNstates) { |
| if (UdpStXn) { |
| if (UdpStX[s]) { |
| Lf->sf &= ~SELNET; |
| Lf->sf |= SELEXCLF; |
| return; |
| } |
| } |
| if (UdpStIn) { |
| if (UdpStI[s]) { |
| UdpStI[s] = 2; |
| Lf->sf |= SELNET; |
| } else { |
| Lf->sf |= SELEXCLF; |
| return; |
| } |
| } |
| } |
| } |
| if (!(Lf->sf & SELNET) && TcpStIn && !UdpStIn) { |
| if (Fnet) { |
| if (!FnetTy |
| || (FnetTy == 4) && (af == AF_INET) |
| |
| #if defined(HASIPv6) |
| || (FnetTy == 6) && (af == AF_INET6) |
| #endif /* defined(HASIPv6) */ |
| |
| ) { |
| Lf->sf |= SELNET; |
| } |
| } |
| } |
| continue; |
| } |
| } |
| if (ics) { |
| |
| /* |
| * Print stream head's q_ptr address as protocol control block address. |
| */ |
| if (pcb) |
| enter_dev_ch(print_kptr(pcb, (char *)NULL, 0)); |
| if (strncmp(Lf->iproto, "UDP", 3) == 0) { |
| |
| /* |
| * Save UDP address and TPI state. |
| */ |
| |
| #if solaris<20600 |
| la = (unsigned char *)&ic.ipc_udp_addr; |
| p = (u_short)ic.ipc_udp_port; |
| #else /* solaris>=20600 */ |
| # if solaris>=110000 |
| af = (uc.udp_ipversion == IPV6_VERSION) ? AF_INET6 : AF_INET; |
| la = (af == AF_INET6) ? (unsigned char *)&uc.udp_v6src |
| : (unsigned char *)&V4_PART_OF_V6(uc.udp_v6src); |
| p = (u_short)uc.udp_port; |
| # else /* solaris<110000 */ |
| # if defined(HASIPv6) |
| la = (af == AF_INET6) ? (unsigned char *)&ic.ipc_v6laddr |
| : (unsigned char *)IPv6_2_IPv4(&ic.ipc_v6laddr); |
| # else /* !defined(HASIPv6 */ |
| la = (unsigned char *)&ic.ipc_laddr; |
| # endif /* defined(HASIPv6) */ |
| |
| p = (u_short)ic.ipc_lport; |
| # endif /* solaris>=110000 */ |
| #endif /* solaris<20600 */ |
| |
| #if solaris<110000 |
| if (IPv_ADDR_UNSPEC(af, la) && !p && ucs) { |
| |
| /* |
| * If the ipc_s structure has no local address, use |
| * the port in the ud_s structure. |
| */ |
| s = (u_short *)&uc.udp_port[0]; |
| p = *s; |
| } |
| |
| # if defined(HASIPv6) |
| if ((af == AF_INET6) && la |
| && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)la)) { |
| |
| /* |
| * Convert a local IPv4 address in an IPv6 structure to an IPv4 |
| * address in an IPv4 structure. Change the address family to |
| * AF_INET. |
| */ |
| la = (unsigned char *)IPv6_2_IPv4(la); |
| af = AF_INET; |
| } |
| # endif /* defined(HASIPv6) */ |
| #endif /* solaris<110000 */ |
| |
| (void) ent_inaddr(la, (int)ntohs(p), (unsigned char *)NULL, |
| -1, af); |
| if (!Fsize) |
| Lf->off_def = 1; |
| if (ucs) { |
| Lf->lts.type = 1; |
| Lf->lts.state.ui = (unsigned int)uc.udp_state; |
| } |
| } else if (strncmp(Lf->iproto, "TCP", 3) == 0) { |
| if (ics) { |
| |
| /* |
| * Save TCP address. |
| */ |
| |
| #if solaris<20400 |
| la = (unsigned char *)&ic.ipc_tcp_addr[0]; |
| p = (u_short)ic.ipc_tcp_addr[5]; |
| #else /* solaris>=20400 */ |
| # if solaris<20600 |
| la = (unsigned char *)&ic.ipc_tcp_laddr; |
| p = (u_short)((short *)&ic.ipc_tcp_ports)[1]; |
| # else /* solaris>=20600 */ |
| # if solaris>=110000 |
| la = (af == AF_INET6) |
| ? (unsigned char *)&cs.connua_v6addr.connua_laddr |
| : (unsigned char *)&cs.conn_src; |
| lp = cs.conn_lport; |
| # else /* solaris<110000 */ |
| # if defined(HASIPv6) |
| la = (af == AF_INET6) ? (unsigned char *)&ic.ipc_v6laddr |
| : (unsigned char *)IPv6_2_IPv4(&ic.ipc_v6laddr); |
| # else /* !defined(HASIPv6 */ |
| la = (unsigned char *)&ic.ipc_laddr; |
| # endif /* defined(HASIPv6) */ |
| |
| p = (u_short)ic.ipc_lport; |
| # endif /* solaris>=110000 */ |
| # endif /* solaris<20600 */ |
| #endif /* solaris<20400 */ |
| |
| #if solaris<110000 |
| if (IPv_ADDR_UNSPEC(af, la) && !p && tcs) { |
| |
| /* |
| * If the ipc_s structure has no local address, use the |
| * local address in the stream's tcp_iph structure (except |
| * for Solaris 2.4), and the port number in the stream's |
| * tcph structure. |
| */ |
| |
| # if solaris!=20400 && solaris<80000 |
| la = (unsigned char *)&tc.tcp_iph.iph_src[0]; |
| # else /* solaris==20400 || solaris<80000 */ |
| # if solaris>=100000 && defined(HAS_IPCLASSIFIER_H) |
| la = (af == AF_INET6) ? (unsigned char *)&ic.conn_srcv6 |
| : (unsigned char *)IPv6_2_IPv4(&ic.conn_srcv6); |
| # else /* solaris<100000 || !defined(HAS_IPCLASSIFIER_H) */ |
| # if solaris>=80000 |
| # if defined(HASIPv6) |
| la = (af == AF_INET6) |
| ? (unsigned char *)&tcb.tcpb_ip_src_v6 |
| : (unsigned char *)IPv6_2_IPv4(&tcb.tcpb_ip_src_v6); |
| # else /* !defined(HASIPv6) */ |
| la = (unsigned char *)&tcb.tcpb_ip_src; |
| # endif /* defined(HASIPv6) */ |
| # endif /* solaris>=80000 */ |
| # endif /* solaris>=100000 && defined(HAS_IPCLASSIFIER_H) */ |
| # endif /* solaris!=20400 && !defined(HASIPv6) */ |
| |
| if (tc.tcp_hdr_len && tc.tcp_tcph |
| && !kread((KA_T)tc.tcp_tcph, (char *)&th, sizeof(th)) |
| ) { |
| tha = &th; |
| s = (u_short *)&th.th_lport[0]; |
| p = *s; |
| } |
| } |
| #endif /* solaris<110000 */ |
| |
| lp = (int)ntohs(p); |
| |
| #if solaris<20400 |
| if ((int)ic.ipc_tcp_addr[2] != INADDR_ANY |
| || ic.ipc_tcp_addr[4] != 0) |
| { |
| fa = (unsigned char *)&ic.ipc_tcp_addr[2]; |
| fp = (int)ntohs(ic.ipc_tcp_addr[4]); |
| } |
| #else /* solaris>=20400 */ |
| # if solaris<20600 |
| if ((int)ic.ipc_tcp_faddr != INADDR_ANY |
| || ((u_short *) &ic.ipc_tcp_ports)[0] != 0) |
| { |
| fa = (unsigned char *)&ic.ipc_tcp_faddr; |
| fp = (int)ntohs(((u_short *)&ic.ipc_tcp_ports)[0]); |
| } |
| # else /* solaris>=20600 */ |
| |
| # if solaris>=110000 |
| ta = (af == AF_INET6) |
| ? (unsigned char *)&cs.connua_v6addr.connua_faddr |
| : (unsigned char *)&cs.conn_rem; |
| if (!IPv_ADDR_UNSPEC(af, ta) || ((u_short)cs.conn_fport)) { |
| fa = ta; |
| fp = (u_short)cs.conn_fport; |
| } |
| # else /* solaris<110000 */ |
| # if defined(HASIPv6) |
| ta = (af == AF_INET6) ? (unsigned char *)&ic.ipc_v6faddr |
| : (unsigned char *)IPv6_2_IPv4(&ic.ipc_v6faddr); |
| # else /* !defined(HASIPv6) */ |
| ta = (unsigned char *)&ic.ipc_faddr; |
| # endif /* defined(HASIPv6) */ |
| |
| if (!IPv_ADDR_UNSPEC(af, ta) || ((u_short)ic.ipc_fport)) { |
| fa = ta; |
| fp = (int)ntohs(((u_short)ic.ipc_fport)); |
| } |
| # endif /* solaris>=110000 */ |
| # endif /* solaris<20600 */ |
| #endif /* solaris <20400 */ |
| |
| #if defined(HASIPv6) |
| if ((af == AF_INET6) |
| && ((la && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)la)) |
| || ((fa && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)fa)))) |
| ) { |
| |
| /* |
| * Convert IPv4 addresses in IPv6 structures to IPv4 |
| * addresses in IPv4 structures. Change the address |
| * family to AF_INET. |
| */ |
| if (la) |
| la = (unsigned char *)IPv6_2_IPv4(la); |
| if (fa) |
| fa = (unsigned char *)IPv6_2_IPv4(fa); |
| af = AF_INET; |
| } |
| #endif /* defined(HASIPv6) */ |
| |
| if (fa || la) |
| (void) ent_inaddr(la, lp, fa, fp, af); |
| } |
| /* |
| * Save TCP state information. |
| */ |
| if (tcs) { |
| (void) save_TCP_states(&tc, (caddr_t *)tha, tcbp, |
| (caddr_t *)NULL); |
| Lf->lts.type = 0; |
| Lf->lts.state.i = (int)tc.tcp_state; |
| } |
| /* |
| * Save TCP size information. |
| */ |
| |
| if (tcs) |
| (void) save_TCP_size(&tc); |
| } |
| } else |
| (void) strcat(Namech, "no TCP/UDP/IP information available"); |
| /* |
| * Enter name characters if there are some. |
| */ |
| if (Namech[0]) |
| enter_nm(Namech); |
| } |
| |
| |
| #if solaris>=110000 |
| /* |
| * read_icmp_t() - read connections icmp_t info |
| */ |
| |
| static int |
| read_icmp_t(va, ph, ia, ic) |
| KA_T va; /* containing vnode kernel address */ |
| KA_T ph; /* containing protocol handle kernel |
| * address */ |
| KA_T ia; /* icmp_t structure's kernel address */ |
| icmp_t *ic; /* local icmp_t receiver */ |
| { |
| char tbuf[32], tbuf1[32]; /* print_kptr() temporary buffers */ |
| |
| # if defined(HAS_CONN_NEW) |
| struct conn_s cs; /* connection structure */ |
| KA_T ka; /* kernel address */ |
| |
| zeromem((char *)ic, sizeof(icmp_t)); |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| (void) CTF_init(&IRU_ctfs, IRU_MOD_FORMAT, IRU_requests); |
| if (!ia |
| || CTF_MEMBER_READ(ia, ic, icmp_t_members, icmp_state) |
| |
| # if defined(HAS_CONN_NEW) |
| || CTF_MEMBER_READ(ia, ic, icmp_t_members, icmp_connp) |
| # else /* !defined(HAS_CONN_NEW) */ |
| || CTF_MEMBER_READ(ia, ic, icmp_t_members, icmp_bound_v6src) |
| || CTF_MEMBER_READ(ia, ic, icmp_t_members, icmp_v6src) |
| || CTF_MEMBER_READ(ia, ic, icmp_t_members, icmp_debug) |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| ) { |
| (void) snpf(Namech, Namechl - 1, |
| "vnode at %s; proto handle at %s; can't read icmp_t at %s", |
| print_kptr(va, tbuf, sizeof(tbuf)), |
| print_kptr(ph, tbuf1, sizeof(tbuf1)), |
| print_kptr(ia, (char *)NULL, 0)); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| |
| # if defined(HAS_CONN_NEW) |
| if ((ka = (KA_T)ic->icmp_connp) |
| && !kread(ka, (char *)&cs, sizeof(cs))) |
| { |
| struct ip_xmit_attr_s xa; |
| |
| /* |
| * Complete the icmp_t structure from the conn_s structure. |
| */ |
| ic->icmp_bound_v6src = cs.conn_bound_addr_v6; |
| ic->icmp_v6src = cs.conn_saddr_v6; |
| ic->icmp_debug.icmp_Debug = cs.conn_debug; |
| ic->icmp_debug.icmp_broadcast = cs.conn_broadcast; |
| ic->icmp_debug.icmp_reuseaddr = cs.conn_reuseaddr; |
| ic->icmp_debug.icmp_useloopback = cs.conn_useloopback; |
| ic->icmp_debug.icmp_dgram_errind = cs.conn_dgram_errind; |
| if ((ka = (KA_T)cs.conn_ixa) |
| && !kread(ka, (char *)&xa, sizeof(xa)) |
| ) { |
| ic->icmp_debug.icmp_dontroute = (xa.ixa_flags & IXAF_DONTROUTE) |
| ? 1 : 0; |
| } |
| |
| } |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| return(0); |
| } |
| |
| |
| /* |
| * read_rts_t() - read connections rts_t info |
| */ |
| |
| static int |
| read_rts_t(va, ph, ra, rt) |
| KA_T va; /* containing vnode kernel address */ |
| KA_T ph; /* containing protocol handle kernel |
| * address */ |
| KA_T ra; /* rts_t structure's kernel address */ |
| rts_t *rt; /* local rts_t receiver */ |
| { |
| char tbuf[32], tbuf1[32]; /* print_kptr() temporary buffers */ |
| |
| # if defined(HAS_CONN_NEW) |
| struct conn_s cs; /* connextion structure */ |
| KA_T ka; /* kernal address */ |
| |
| zeromem((char *)rt, sizeof(rts_t)); |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| (void) CTF_init(&IRU_ctfs, IRU_MOD_FORMAT, IRU_requests); |
| if (!ra |
| || CTF_MEMBER_READ(ra, rt, rts_t_members, rts_state) |
| |
| # if defined(HAS_CONN_NEW) |
| || CTF_MEMBER_READ(ra, rt, rts_t_members, rts_connp) |
| # else /* !defined(HAS_CONN_NEW) */ |
| || CTF_MEMBER_READ(ra, rt, rts_t_members, rts_debug) |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| ) { |
| (void) snpf(Namech, Namechl - 1, |
| "vnode at %s; proto handle at %s; can't read rts_t at %s", |
| print_kptr(va, tbuf, sizeof(tbuf)), |
| print_kptr(ph, tbuf1, sizeof(tbuf1)), |
| print_kptr(ra, (char *)NULL, 0)); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| |
| # if defined(HAS_CONN_NEW) |
| if ((ka = (KA_T)rt->rts_connp) |
| && !kread(ka, (char *)&cs, sizeof(struct conn_s)) |
| ) { |
| struct ip_xmit_attr_s xa; |
| |
| /* |
| * Fill in rts_debug from the connection structure. |
| */ |
| rt->rts_debug.rts_Debug = cs.conn_debug; |
| rt->rts_debug.rts_broadcast = cs.conn_broadcast; |
| rt->rts_debug.rts_reuseaddr = cs.conn_reuseaddr; |
| rt->rts_debug.rts_useloopback = cs.conn_useloopback; |
| if ((ka = (KA_T)cs.conn_ixa) |
| && !kread(ka, (char *)&xa, sizeof(xa)) |
| ) { |
| rt->rts_debug.rts_dontroute = (xa.ixa_flags & IXAF_DONTROUTE) |
| ? 1 : 0; |
| } |
| } |
| |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| return(0); |
| } |
| |
| |
| /* |
| * read_udp_t() - read UDP control structure |
| */ |
| |
| static int |
| read_udp_t(ua, uc) |
| KA_T ua; /* ucp_t kernel address */ |
| udp_t *uc; /* receiving udp_t structure */ |
| { |
| (void) CTF_init(&IRU_ctfs, IRU_MOD_FORMAT, IRU_requests); |
| if (!ua |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_state) |
| |
| # if defined(HAS_CONN_NEW) |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_connp) |
| # else /* !defined(HAS_CONN_NEW) */ |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_port) |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_dstport) |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_v6src) |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_v6dst) |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_ipversion) |
| || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_bits) |
| # endif /* defined(HAS_CONN_NEW) */ |
| |
| ) { |
| (void) snpf(Namech, Namechl, "can't read udp_t: %s", |
| print_kptr(ua, (char *)NULL, 0)); |
| Namech[Namechl - 1] = '\0'; |
| enter_nm(Namech); |
| return(1); |
| } |
| return(0); |
| } |
| #endif /* solaris>=110000 */ |
| |
| |
| /* |
| * save_TCP_size() -- save TCP size information |
| */ |
| |
| static void |
| |
| save_TCP_size(tc) |
| tcp_t *tc; /* pointer to TCP control structure */ |
| { |
| int rq, sq; |
| |
| #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) < 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) */ |
| Lf->off_def = 1; |
| #endif /* defined(HASTCPTPIQ) || defined(HASTCPTPIW) */ |
| |
| } |
| |
| |
| /* |
| * save_TCP_states() - save TCP states |
| */ |
| |
| static void |
| save_TCP_states(tc, fa, tb, xp) |
| tcp_t *tc; /* pointer to TCP control structure */ |
| caddr_t *fa; /* flags address (may be NULL): |
| * if HAS_CONN_NEW: conn_s * |
| * if !CONN_HAS_NEW: tcph_t * |
| */ |
| tcpb_t *tb; /* pointer to TCP base structure (may |
| * be NULL) */ |
| caddr_t *xp; /* pointer to struct ip_xmit_attr_s if |
| * HAS_CONN_NEW (may be NULL) */ |
| { |
| if (!tc) |
| return; |
| |
| #if defined(HASSOOPT) |
| # if defined(HAS_CONN_NEW) |
| if (Ftcptpi & TCPTPI_FLAGS && fa) { |
| struct conn_s *cs = (struct conn_s *)fa; |
| |
| if (cs->conn_broadcast) |
| Lf->lts.opt |= SO_BROADCAST; |
| if (cs->conn_debug) |
| Lf->lts.opt |= SO_DEBUG; |
| if (cs->conn_dgram_errind) |
| Lf->lts.opt |= SO_DGRAM_ERRIND; |
| if (xp && (((ip_xmit_attr_t *)xp)->ixa_flags & IXAF_DONTROUTE)) |
| Lf->lts.opt |= SO_DONTROUTE; |
| if (cs->conn_keepalive) { |
| Lf->lts.opt |= SO_KEEPALIVE; |
| Lf->lts.kai = (unsigned int)tc->tcp_ka_interval; |
| } |
| if (cs->conn_linger) { |
| Lf->lts.opt |= SO_LINGER; |
| Lf->lts.ltm = (unsigned int)cs->conn_lingertime; |
| } |
| if (cs->conn_oobinline) |
| Lf->lts.opt |= SO_OOBINLINE; |
| Lf->lts.pqlen = (unsigned int)tc->tcp_conn_req_cnt_q0; |
| Lf->lts.qlen = (unsigned int)tc->tcp_conn_req_cnt_q; |
| Lf->lts.qlim = (unsigned int)tc->tcp_conn_req_max; |
| Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims |
| = (unsigned char)1; |
| if (cs->conn_reuseaddr) |
| Lf->lts.opt |= SO_REUSEADDR; |
| if (cs->conn_useloopback) |
| Lf->lts.opt |= SO_USELOOPBACK; |
| # else /* !defined(HAS_CONN_NEW) */ |
| if (Ftcptpi & TCPTPI_FLAGS) { |
| if (tc->tcp_broadcast) |
| Lf->lts.opt |= SO_BROADCAST; |
| if (tc->tcp_debug) |
| Lf->lts.opt |= SO_DEBUG; |
| if (tc->tcp_dgram_errind) |
| Lf->lts.opt |= SO_DGRAM_ERRIND; |
| if (tc->tcp_dontroute) |
| Lf->lts.opt |= SO_DONTROUTE; |
| if (tc->KEEPALIVE_INTERVAL) { |
| Lf->lts.opt |= SO_KEEPALIVE; |
| Lf->lts.kai = (unsigned int)tc->KEEPALIVE_INTERVAL; |
| } |
| if (tc->tcp_linger) { |
| Lf->lts.opt |= SO_LINGER; |
| Lf->lts.ltm = (unsigned int)tc->tcp_lingertime; |
| } |
| if (tc->tcp_oobinline) |
| Lf->lts.opt |= SO_OOBINLINE; |
| Lf->lts.pqlen = (unsigned int)tc->tcp_conn_req_cnt_q0; |
| Lf->lts.qlen = (unsigned int)tc->tcp_conn_req_cnt_q; |
| Lf->lts.qlim = (unsigned int)tc->tcp_conn_req_max; |
| Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims |
| = (unsigned char)1; |
| |
| # if solaris>=80000 |
| # if defined(HAS_IPCLASSIFIER_H) |
| if (tc->tcp_reuseaddr) |
| # else /* !defined(HAS_IPCLASSIFIER_H) */ |
| if (tb && tb->tcpb_reuseaddr) |
| # endif /* !defined(HAS_IPCLASSIFIER_H) */ |
| |
| Lf->lts.opt |= SO_REUSEADDR; |
| # endif /* solaris>=80000 */ |
| |
| if (tc->tcp_useloopback) |
| Lf->lts.opt |= SO_USELOOPBACK; |
| # endif /* defined(HAS_CONN_NEW) */ |
| #endif /* defined(HASSOOPT) */ |
| |
| #if defined(HASTCPOPT) |
| # if defined(ACK_TIMER) |
| # if !defined(HAS_CONN_NEW) |
| if (fa && (((tcph_t *)fa)->th_flags[0] & ACK_TIMER)) |
| Lf->lts.topt |= TF_DELACK; |
| # endif /* !defined(HAS_CONN_NEW) */ |
| # endif /* defined(ACK_TIMER) */ |
| |
| # if solaris<80000 || defined(HAS_IPCLASSIFIER_H) |
| Lf->lts.mss = (unsigned long)tc->tcp_mss; |
| # else /* solaris>=80000 && !defined(HAS_IPCLASSIFIER_H) */ |
| if (tb) |
| Lf->lts.mss = (unsigned long)tb->tcpb_mss; |
| # endif /* solaris<80000 || defined(HAS_IPCLASSIFIER_H) */ |
| |
| Lf->lts.msss = (unsigned char)1; |
| if (tc->tcp_naglim == 1L) |
| Lf->lts.topt |= TF_NODELAY; |
| if (tc->tcp_fin_sent) |
| Lf->lts.topt |= TF_SENTFIN; |
| } |
| #endif /* defined(HASTCPOPT) */ |
| |
| } |