Beispiel #1
0
void
socktrans(struct socket *sock, int i)
{
    static const char *stypename[] = {
        "unused",	/* 0 */
        "stream", 	/* 1 */
        "dgram",	/* 2 */
        "raw",		/* 3 */
        "rdm",		/* 4 */
        "seqpak"	/* 5 */
    };
#define	STYPEMAX 5
    struct socket	so;
    struct protosw	proto;
    struct domain	dom;
    struct inpcb	inpcb;
    struct unpcb	unpcb;
    int len;
    char dname[32];

    PREFIX(i);

    /* fill in socket */
    if (!kread(sock, &so, sizeof(struct socket))) {
        dprintf(stderr, "can't read sock at %p\n", (void *)sock);
        goto bad;
    }

    /* fill in protosw entry */
    if (!kread(so.so_proto, &proto, sizeof(struct protosw))) {
        dprintf(stderr, "can't read protosw at %p",
                (void *)so.so_proto);
        goto bad;
    }

    /* fill in domain */
    if (!kread(proto.pr_domain, &dom, sizeof(struct domain))) {
        dprintf(stderr, "can't read domain at %p\n",
                (const void *)proto.pr_domain);
        goto bad;
    }

    if ((len = kvm_read(kd, (u_long)dom.dom_name, dname,
                        sizeof(dname) - 1)) < 0) {
        dprintf(stderr, "can't read domain name at %p\n",
                (void *)dom.dom_name);
        dname[0] = '\0';
    }
    else
        dname[len] = '\0';

    if ((u_short)so.so_type > STYPEMAX)
        printf("* %s ?%d", dname, so.so_type);
    else
        printf("* %s %s", dname, stypename[so.so_type]);

    /*
     * protocol specific formatting
     *
     * Try to find interesting things to print.  For tcp, the interesting
     * thing is the address of the tcpcb, for udp and others, just the
     * inpcb (socket pcb).  For unix domain, its the address of the socket
     * pcb and the address of the connected pcb (if connected).  Otherwise
     * just print the protocol number and address of the socket itself.
     * The idea is not to duplicate netstat, but to make available enough
     * information for further analysis.
     */
    switch(dom.dom_family) {
    case AF_INET:
    case AF_INET6:
        getinetproto(proto.pr_protocol);
        if (proto.pr_protocol == IPPROTO_TCP ) {
            if (so.so_pcb) {
                if (kvm_read(kd, (u_long)so.so_pcb,
                             (char *)&inpcb, sizeof(struct inpcb))
                        != sizeof(struct inpcb)) {
                    dprintf(stderr,
                            "can't read inpcb at %p\n",
                            (void *)so.so_pcb);
                    goto bad;
                }
                printf(" %lx", (u_long)inpcb.inp_ppcb);
            }
        }
        else if (so.so_pcb)
            printf(" %lx", (u_long)so.so_pcb);
        break;
    case AF_UNIX:
        /* print address of pcb and connected pcb */
        if (so.so_pcb) {
            printf(" %lx", (u_long)so.so_pcb);
            if (kvm_read(kd, (u_long)so.so_pcb, (char *)&unpcb,
                         sizeof(struct unpcb)) != sizeof(struct unpcb)) {
                dprintf(stderr, "can't read unpcb at %p\n",
                        (void *)so.so_pcb);
                goto bad;
            }
            if (unpcb.unp_conn) {
                char shoconn[4], *cp;

                cp = shoconn;
                if (!(so.so_state & SS_CANTRCVMORE))
                    *cp++ = '<';
                *cp++ = '-';
                if (!(so.so_state & SS_CANTSENDMORE))
                    *cp++ = '>';
                *cp = '\0';
                printf(" %s %lx", shoconn,
                       (u_long)unpcb.unp_conn);
            }
        }
        break;
    default:
        /* print protocol number and socket address */
        printf(" %d %lx", proto.pr_protocol, (u_long)sock);
    }
    printf("\n");
    return;
bad:
    printf("* error\n");
}
Beispiel #2
0
void
socktrans(struct socket *sock, int i)
{
	static char *stypename[] = {
		"unused",	/* 0 */
		"stream",	/* 1 */
		"dgram",	/* 2 */
		"raw",		/* 3 */
		"rdm",		/* 4 */
		"seqpak"	/* 5 */
	};
#define	STYPEMAX 5
	struct socket	so;
	struct protosw	proto;
	struct domain	dom;
	struct inpcb	inpcb;
	struct unpcb	unpcb;
	int len;
	char dname[32];
#ifdef INET6
	char xaddrbuf[NI_MAXHOST + 2];
#endif

	PREFIX(i);

	/* fill in socket */
	if (!KVM_READ(sock, &so, sizeof(struct socket))) {
		dprintf("can't read sock at %p", sock);
		goto bad;
	}

	/* fill in protosw entry */
	if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) {
		dprintf("can't read protosw at %p", so.so_proto);
		goto bad;
	}

	/* fill in domain */
	if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) {
		dprintf("can't read domain at %p", proto.pr_domain);
		goto bad;
	}

	if ((len = kvm_read(kd, (u_long)dom.dom_name, dname,
	    sizeof(dname) - 1)) != sizeof(dname) -1) {
		dprintf("can't read domain name at %p", dom.dom_name);
		dname[0] = '\0';
	} else
		dname[len] = '\0';

	if ((u_short)so.so_type > STYPEMAX)
		printf("* %s ?%d", dname, so.so_type);
	else
		printf("* %s %s", dname, stypename[so.so_type]);

	/*
	 * protocol specific formatting
	 *
	 * Try to find interesting things to print.  For tcp, the interesting
	 * thing is the address of the tcpcb, for udp and others, just the
	 * inpcb (socket pcb).  For unix domain, its the address of the socket
	 * pcb and the address of the connected pcb (if connected).  Otherwise
	 * just print the protocol number and address of the socket itself.
	 * The idea is not to duplicate netstat, but to make available enough
	 * information for further analysis.
	 */
	switch(dom.dom_family) {
	case AF_INET:
		getinetproto(proto.pr_protocol);
		if (proto.pr_protocol == IPPROTO_TCP) {
			if (so.so_pcb == NULL)
				break;
			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb,
			    sizeof(struct inpcb)) != sizeof(struct inpcb)) {
				dprintf("can't read inpcb at %p", so.so_pcb);
				goto bad;
			}
			printf(" %p", inpcb.inp_ppcb);
			printf(" %s:%d",
			    inpcb.inp_laddr.s_addr == INADDR_ANY ? "*" :
			    inet_ntoa(inpcb.inp_laddr),
			    ntohs(inpcb.inp_lport));
			if (inpcb.inp_fport) {
				if (so.so_state & SS_CONNECTOUT)
					printf(" --> ");
				else
					printf(" <-- ");
				printf("%s:%d",
				    inpcb.inp_faddr.s_addr == INADDR_ANY ? "*" :
				    inet_ntoa(inpcb.inp_faddr),
				    ntohs(inpcb.inp_fport));
			}
		} else if (proto.pr_protocol == IPPROTO_UDP) {
			if (so.so_pcb == NULL)
				break;
			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb,
			    sizeof(struct inpcb)) != sizeof(struct inpcb)) {
				dprintf("can't read inpcb at %p", so.so_pcb);
				goto bad;
			}
			printf(" %s:%d",
			    inpcb.inp_laddr.s_addr == INADDR_ANY ? "*" :
			    inet_ntoa(inpcb.inp_laddr),
			    ntohs(inpcb.inp_lport));
			if (inpcb.inp_fport)
				printf(" <-> %s:%d",
				    inpcb.inp_faddr.s_addr == INADDR_ANY ? "*" :
				    inet_ntoa(inpcb.inp_faddr),
				    ntohs(inpcb.inp_fport));
		} else if (so.so_pcb)
			printf(" %p", so.so_pcb);
		break;
#ifdef INET6
	case AF_INET6:
		getinetproto(proto.pr_protocol);
		if (proto.pr_protocol == IPPROTO_TCP) {
			if (so.so_pcb == NULL)
				break;
			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb,
			    sizeof(struct inpcb)) != sizeof(struct inpcb)) {
				dprintf("can't read inpcb at %p", so.so_pcb);
				goto bad;
			}
			printf(" %p", inpcb.inp_ppcb);
			snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
			    inet6_addrstr(&inpcb.inp_laddr6));
			printf(" %s:%d",
			    IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_laddr6) ? "*" :
			    xaddrbuf,
			    ntohs(inpcb.inp_lport));
			if (inpcb.inp_fport) {
				if (so.so_state & SS_CONNECTOUT)
					printf(" --> ");
				else
					printf(" <-- ");
				snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
				    inet6_addrstr(&inpcb.inp_faddr6));
				printf("%s:%d",
				    IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_faddr6) ? "*" :
				    xaddrbuf,
				    ntohs(inpcb.inp_fport));
			}
		} else if (proto.pr_protocol == IPPROTO_UDP) {
			if (so.so_pcb == NULL)
				break;
			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb,
			    sizeof(struct inpcb)) != sizeof(struct inpcb)) {
				dprintf("can't read inpcb at %p", so.so_pcb);
				goto bad;
			}
			snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
			    inet6_addrstr(&inpcb.inp_laddr6));
			printf(" %s:%d",
			    IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_laddr6) ? "*" :
			    xaddrbuf,
			    ntohs(inpcb.inp_lport));
			if (inpcb.inp_fport) {
				snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
				    inet6_addrstr(&inpcb.inp_faddr6));
				printf(" <-> %s:%d",
				    IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_faddr6) ? "*" :
				    xaddrbuf,
				    ntohs(inpcb.inp_fport));
			}
		} else if (so.so_pcb)
			printf(" %p", so.so_pcb);
		break;
#endif
	case AF_UNIX:
		/* print address of pcb and connected pcb */
		if (so.so_pcb) {
			printf(" %p", so.so_pcb);
			if (kvm_read(kd, (u_long)so.so_pcb, (char *)&unpcb,
			    sizeof(struct unpcb)) != sizeof(struct unpcb)){
				dprintf("can't read unpcb at %p", so.so_pcb);
				goto bad;
			}
			if (unpcb.unp_conn) {
				char shoconn[4], *cp;

				cp = shoconn;
				if (!(so.so_state & SS_CANTRCVMORE))
					*cp++ = '<';
				*cp++ = '-';
				if (!(so.so_state & SS_CANTSENDMORE))
					*cp++ = '>';
				*cp = '\0';
				printf(" %s %p", shoconn,
				    unpcb.unp_conn);
			}
		}
		break;
	default:
		/* print protocol number and socket address */
		printf(" %d %p", proto.pr_protocol, sock);
	}
	printf("\n");
	return;
bad:
	printf("* error\n");
}