Esempio n. 1
0
void
ipx_printhost(struct ipx_addr *addr)
{
	u_short port;
	struct ipx_addr work = *addr;
	char *p; u_char *q;
	char *net = "", *host = "";
	char cport[10], chost[15], cnet[15];

	port = ntohs(work.x_port);

	if (ipx_nullnet(work) && ipx_nullhost(work)) {

		if (port)
			kprintf("*.%x", port);
		else
			kprintf("*.*");

		return;
	}

	if (ipx_wildnet(work))
		net = "any";
	else if (ipx_nullnet(work))
		net = "*";
	else {
		q = work.x_net.c_net;
		ksnprintf(cnet, sizeof(cnet), "%x%x%x%x",
			q[0], q[1], q[2], q[3]);
		for (p = cnet; *p == '0' && p < cnet + 8; p++)
			continue;
		net = p;
	}

	if (ipx_wildhost(work))
		host = "any";
	else if (ipx_nullhost(work))
		host = "*";
	else {
		q = work.x_host.c_host;
		ksnprintf(chost, sizeof(chost), "%x%x%x%x%x%x",
			q[0], q[1], q[2], q[3], q[4], q[5]);
		for (p = chost; *p == '0' && p < chost + 12; p++)
			continue;
		host = p;
	}

	if (port) {
		if (strcmp(host, "*") == 0) {
			host = "";
			ksnprintf(cport, sizeof(cport), "%x", port);
		} else
			ksnprintf(cport, sizeof(cport), ".%x", port);
	} else
		*cport = 0;

	kprintf("%s.%s%s", net, host, cport);
}
Esempio n. 2
0
void
ipxprotopr(u_long off, const char *name, int af1 __unused, int proto __unused)
{
	struct ipxpcbhead cb;
	struct ipxpcb *ipxp;
	struct ipxpcb ipxpcb;
	struct spxpcb spxpcb;
	struct socket sockb;
	static int first = 1;
	int isspx;

	if (off == 0)
		return;

	isspx = strcmp(name, "spx") == 0;
	kread(off, (char *)&cb, sizeof (struct ipxpcbhead));
	ipxp = LIST_FIRST(&cb);
	while (ipxp != NULL) {
		u_long ppcb;

		kread((u_long)ipxp, (char *)&ipxpcb, sizeof (ipxpcb));
		ipxp = LIST_NEXT(&ipxpcb, ipxp_list);

		if (!aflag && ipx_nullhost(ipxpcb.ipxp_faddr) ) {
			continue;
		}
		kread((u_long)ipxpcb.ipxp_socket,
				(char *)&sockb, sizeof (sockb));
		ppcb = (u_long) ipxpcb.ipxp_pcb;
		if (ppcb) {
			if (isspx) {
				kread(ppcb, (char *)&spxpcb, sizeof (spxpcb));
			} else continue;
		} else
			if (isspx) continue;
		if (first) {
			printf("Active IPX connections");
			if (aflag)
				printf(" (including servers)");
			putchar('\n');
			if (Aflag)
				printf("%-8.8s ", "PCB");
			printf(Aflag ?
				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
				"Proto", "Recv-Q", "Send-Q",
				"Local Address", "Foreign Address", "(state)");
			first = 0;
		}
		if (Aflag)
			printf("%8lx ", ppcb);
		printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc,
			sockb.so_snd.sb_cc);
		printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_laddr));
		printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_faddr));
		if (isspx) {
			if (spxpcb.s_state >= TCP_NSTATES)
				printf(" %d", spxpcb.s_state);
			else
				printf(" %s", tcpstates[spxpcb.s_state]);
		}
		putchar('\n');
	}
}
Esempio n. 3
0
void
spx_input(struct mbuf *m, struct ipxpcb *ipxp)
{
	struct spxpcb *cb;
	struct spx *si = mtod(m, struct spx *);
	struct socket *so;
	struct spx spx_savesi;
	int dropsocket = 0;
	short ostate = 0;

	spxstat.spxs_rcvtotal++;
	KASSERT(ipxp != NULL, ("spx_input: ipxpcb == NULL"));

	/*
	 * spx_input() assumes that the caller will hold both the pcb list
	 * lock and also the ipxp lock.  spx_input() will release both before
	 * returning, and may in fact trade in the ipxp lock for another pcb
	 * lock following sonewconn().
	 */
	IPX_LIST_LOCK_ASSERT();
	IPX_LOCK_ASSERT(ipxp);

	cb = ipxtospxpcb(ipxp);
	KASSERT(cb != NULL, ("spx_input: cb == NULL"));

	if (ipxp->ipxp_flags & IPXP_DROPPED)
		goto drop;

	if (m->m_len < sizeof(*si)) {
		if ((m = m_pullup(m, sizeof(*si))) == NULL) {
			IPX_UNLOCK(ipxp);
			IPX_LIST_UNLOCK();
			spxstat.spxs_rcvshort++;
			return;
		}
		si = mtod(m, struct spx *);
	}
	si->si_seq = ntohs(si->si_seq);
	si->si_ack = ntohs(si->si_ack);
	si->si_alo = ntohs(si->si_alo);

	so = ipxp->ipxp_socket;
	KASSERT(so != NULL, ("spx_input: so == NULL"));

#ifdef MAC
	if (mac_socket_check_deliver(so, m) != 0)
		goto drop;
#endif

	if (so->so_options & SO_DEBUG || traceallspxs) {
		ostate = cb->s_state;
		spx_savesi = *si;
	}
	if (so->so_options & SO_ACCEPTCONN) {
		struct spxpcb *ocb = cb;

		so = sonewconn(so, 0);
		if (so == NULL)
			goto drop;

		/*
		 * This is ugly, but ....
		 *
		 * Mark socket as temporary until we're committed to keeping
		 * it.  The code at ``drop'' and ``dropwithreset'' check the
		 * flag dropsocket to see if the temporary socket created
		 * here should be discarded.  We mark the socket as
		 * discardable until we're committed to it below in
		 * TCPS_LISTEN.
		 *
		 * XXXRW: In the new world order of real kernel parallelism,
		 * temporarily allocating the socket when we're "not sure"
		 * seems like a bad idea, as we might race to remove it if
		 * the listen socket is closed...?
		 *
		 * We drop the lock of the listen socket ipxp, and acquire
		 * the lock of the new socket ippx.
		 */
		dropsocket++;
		IPX_UNLOCK(ipxp);
		ipxp = (struct ipxpcb *)so->so_pcb;
		IPX_LOCK(ipxp);
		ipxp->ipxp_laddr = si->si_dna;
		cb = ipxtospxpcb(ipxp);
		cb->s_mtu = ocb->s_mtu;		/* preserve sockopts */
		cb->s_flags = ocb->s_flags;	/* preserve sockopts */
		cb->s_flags2 = ocb->s_flags2;	/* preserve sockopts */
		cb->s_state = TCPS_LISTEN;
	}
	IPX_LOCK_ASSERT(ipxp);

	/*
	 * Packet received on connection.  Reset idle time and keep-alive
	 * timer.
	 */
	cb->s_idle = 0;
	cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;

	switch (cb->s_state) {
	case TCPS_LISTEN:{
		struct sockaddr_ipx *sipx, ssipx;
		struct ipx_addr laddr;

		/*
		 * If somebody here was carying on a conversation and went
		 * away, and his pen pal thinks he can still talk, we get the
		 * misdirected packet.
		 */
		if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) {
			spx_istat.gonawy++;
			goto dropwithreset;
		}
		sipx = &ssipx;
		bzero(sipx, sizeof *sipx);
		sipx->sipx_len = sizeof(*sipx);
		sipx->sipx_family = AF_IPX;
		sipx->sipx_addr = si->si_sna;
		laddr = ipxp->ipxp_laddr;
		if (ipx_nullhost(laddr))
			ipxp->ipxp_laddr = si->si_dna;
		if (ipx_pcbconnect(ipxp, (struct sockaddr *)sipx, &thread0)) {
			ipxp->ipxp_laddr = laddr;
			spx_istat.noconn++;
			goto drop;
		}
		spx_template(cb);
		dropsocket = 0;		/* committed to socket */
		cb->s_did = si->si_sid;
		cb->s_rack = si->si_ack;
		cb->s_ralo = si->si_alo;
#define THREEWAYSHAKE
#ifdef THREEWAYSHAKE
		cb->s_state = TCPS_SYN_RECEIVED;
		cb->s_force = 1 + SPXT_KEEP;
		spxstat.spxs_accepts++;
		cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
		}
		break;

	 case TCPS_SYN_RECEIVED: {
		/*
		 * This state means that we have heard a response to our
		 * acceptance of their connection.  It is probably logically
		 * unnecessary in this implementation.
		 */
		if (si->si_did != cb->s_sid) {
			spx_istat.wrncon++;
			goto drop;
		}
#endif
		ipxp->ipxp_fport =  si->si_sport;
		cb->s_timer[SPXT_REXMT] = 0;
		cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
		soisconnected(so);
		cb->s_state = TCPS_ESTABLISHED;
		spxstat.spxs_accepts++;
		}
		break;

	case TCPS_SYN_SENT:
		/*
		 * This state means that we have gotten a response to our
		 * attempt to establish a connection.  We fill in the data
		 * from the other side, telling us which port to respond to,
		 * instead of the well-known one we might have sent to in the
		 * first place.  We also require that this is a response to
		 * our connection id.
		 */
		if (si->si_did != cb->s_sid) {
			spx_istat.notme++;
			goto drop;
		}
		spxstat.spxs_connects++;
		cb->s_did = si->si_sid;
		cb->s_rack = si->si_ack;
		cb->s_ralo = si->si_alo;
		cb->s_dport = ipxp->ipxp_fport =  si->si_sport;
		cb->s_timer[SPXT_REXMT] = 0;
		cb->s_flags |= SF_ACKNOW;
		soisconnected(so);
		cb->s_state = TCPS_ESTABLISHED;

		/*
		 * Use roundtrip time of connection request for initial rtt.
		 */
		if (cb->s_rtt) {
			cb->s_srtt = cb->s_rtt << 3;
			cb->s_rttvar = cb->s_rtt << 1;
			SPXT_RANGESET(cb->s_rxtcur,
			    ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1,
			    SPXTV_MIN, SPXTV_REXMTMAX);
			    cb->s_rtt = 0;
		}
	}
Esempio n. 4
0
File: ipx.c Progetto: MarginC/kame
void
ipxprotopr(u_long off, const char *name, int af1 __unused)
{
	struct ipxpcb cb;
	struct ipxpcb *prev, *next;
	int isspx;

	if (off == 0)
		return;
	isspx = strcmp(name, "spx") == 0;
	kread(off, (char *)&cb, sizeof (struct ipxpcb));
	ipxpcb = cb;
	prev = (struct ipxpcb *)off;
	if (ipxpcb.ipxp_next == (struct ipxpcb *)off)
		return;
	for (;ipxpcb.ipxp_next != (struct ipxpcb *)off; prev = next) {
		u_long ppcb;

		next = ipxpcb.ipxp_next;
		kread((u_long)next, (char *)&ipxpcb, sizeof (ipxpcb));
		if (ipxpcb.ipxp_prev != prev) {
			printf("???\n");
			break;
		}
		if (!aflag && ipx_nullhost(ipxpcb.ipxp_faddr) ) {
			continue;
		}
		kread((u_long)ipxpcb.ipxp_socket,
				(char *)&sockb, sizeof (sockb));
		ppcb = (u_long) ipxpcb.ipxp_pcb;
		if (ppcb) {
			if (isspx) {
				kread(ppcb, (char *)&spxpcb, sizeof (spxpcb));
			} else continue;
		} else
			if (isspx) continue;
		if (first) {
			printf("Active IPX connections");
			if (aflag)
				printf(" (including servers)");
			putchar('\n');
			if (Aflag)
				printf("%-8.8s ", "PCB");
			printf(Aflag ?
				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
				"Proto", "Recv-Q", "Send-Q",
				"Local Address", "Foreign Address", "(state)");
			first = 0;
		}
		if (Aflag)
			printf("%8lx ", ppcb);
		printf("%-5.5s %6u %6u ", name, sockb.so_rcv.sb_cc,
			sockb.so_snd.sb_cc);
		printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_laddr));
		printf(Aflag?" %-18.18s":" %-22.22s", ipx_prpr(&ipxpcb.ipxp_faddr));
		if (isspx) {
			extern char *tcpstates[];
			if (spxpcb.s_state >= TCP_NSTATES)
				printf(" %d", spxpcb.s_state);
			else
				printf(" %s", tcpstates[spxpcb.s_state]);
		}
		putchar('\n');
		prev = next;
	}
}