FTP prob in BBN's 4.1BSD Dist?

chris at umcp-cs.UUCP chris at umcp-cs.UUCP
Sun Jul 22 06:21:29 AEST 1984


Well, you didn't say what interface you were using, or which version
of the BBN code, but we found & fixed two nasty problems in il.c in
sys10.  They both have to do with flushing packets in ilrint().  The
first ubaremap()ed virtual address 14 (not even in kernel space!) to
the UNIBUS; the second dropped all packets longer than a single mbuf
once an error occurred on the interface.  The (unrewritten but working)
code:

/*
 * Ethernet interface receiver interrupt.
 * If input error just drop packet.  Use frame header info in first packet
 * for data chaining.
 */
ilrint(unit)
int unit;
{
	register struct ifcb *ip = &ilifcb[unit];
	register struct uba_device *ui = ilinfo[unit];
	register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
	register struct il_rheader *l;
    	register struct mbuf *m, *n;

	if ((m = ip->if_inq_cur) == NULL)
		return;
	/*
	 * If frame input length is zero, we expect start of a new frame.
	 * Get total frame length from rheader, and check status and lengths
	 * for errors.
	 */
	if (ip->if_ilen == 0) {
		l = mtod(m, struct il_rheader *);
		ip->if_ilen = l->ilr_length + 4;

#ifdef ILDEBUG
		printf("il%d: read done ", unit);
		ilprt("RCV", (int)l+2);
		printf("\n");
#endif

		if (l->ilr_status&0x3 || ip->if_ilen < 46+sizeof(struct il_rheader) 
		    || ip->if_ilen > ILMTU) {
			ip->if_error = TRUE;
			ip->if_ierrs++;
#ifdef notdef
			if (ip->if_ierrs % 100 == 0)
				printf("il%d: += 100 input errors\n", unit);
#endif
			printf("il%d: input error (status=%x, len=%d)\n", unit,
			    l->ilr_status, ip->if_ilen);
			goto flush;
		}
	}

	m->m_len = MRND8 - addr->il_bcr;
	if (ip->if_ilen <= MRND8) { 	/* end of message */
		/*
		 * Queue good packet for input processing and awaken net
		 * input process
		 */
		ip->if_ilen = 0;
		if (!ip->if_flush) {
			ip->if_ipkts++;
#ifndef SOFTINT
			if (ip->if_inq_hd != NULL)
				ip->if_inq_tl->m_act = ip->if_inq_msg;
			else
				ip->if_inq_hd = ip->if_inq_msg;
			ip->if_inq_tl = ip->if_inq_msg;
			ip->if_inq_msg = NULL;
			if (netcb.n_flags & NASLEEP) {
				netcb.n_flags &= ~NASLEEP;
				wakeup((caddr_t)&netcb.n_ifcb_hd);	
			}
#else
			ilrcv(ip);
#endif SOFTINT
		}
		/*
		 * Get buffer for next packet to be read.
		 */
		if ((n = m_get(0)) != NULL) {
			/*
			 * Got a buffer; fill it in.
			 */
			ip->if_flush = FALSE;
			ip->if_ilen = 0;
			n->m_off = MHEAD;
			ip->if_inq_msg = n;
			ip->if_inq_cur = n;
		} else {
flush:
			/*
			 * No more buffers: flush 
			 */
			ip->if_flush = TRUE;
			ip->if_inq_msg = n = (struct mbuf *)&netflush;
			ip->if_flushes++;
		}
	} else {
		/*
		 * Not end of packet; if not flushing
		 * try to get more buffers.  If there is
		 * an error or no more buffers free partial message.
		 */
		ip->if_ilen -= m->m_len;
		if (!ip->if_flush) {
			if (!ip->if_error && (n = m_get(0)) != NULL) {
				m->m_next = n;
				n->m_off = MHEAD;
				ip->if_inq_cur = n;
			} else {
				m_freem(ip->if_inq_msg);
				ip->if_flush = TRUE;
				ip->if_error = FALSE;
				n = (struct mbuf *)&netflush;
				ip->if_inq_cur = n;
				ip->if_inq_msg = n;
				ip->if_flushes++;
			}
		} else
			n = &netflush;		/* Continue flushing */
	}
	/*
	 * Reset for next packet if possible.
	 * If waiting for transmit command completion, set flag
	 * and wait until command completes.
	 */
setup:
	if (!ip->if_active)
		ilread(ip, (caddr_t)((int)n + MHEAD), MRND8);
	else
		ip->if_startrcv = TRUE;
}	
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris at umcp-cs		ARPA:	chris at maryland



More information about the Comp.unix.wizards mailing list