[mod.protocols.appletalk] gw code

cck%cunixc@COLUMBIA.EDU.UUCP (12/09/86)

Bill Schilit found the following problem with the udp code.

Basically, the Kinetics gateway running the udp code cannot send or
receive full size ip encapsulated AppleTalk packets.

 Problem: Kinetics gateway doesn't seem to forward full sized or nearly
full sized appletalk packets from the Appletalk to Ethernet.
 Analysis: TBSZ in ie.h only accounts for 630 bytes.  With all ip,
udp, and ethernet headers added in, we need 645 bytes.
 Solution: Assume MAXDATA refers only to AppleTalk data.  Increase
TBSZ byte ETHER_HEADERS=(sizeof(udp header) + sizeof(ip header) +
sizeof(ethernet header)) to account for additional data.  Note: this
take buffer to 672 bytes which is more than adequate.  [Alternatively,
set TBSZ to 645 (603 maximum appletalk data + 42 for udp
encapsulation), but this isn't as conservative.]

 Problem: Kinetics gateway doesn't seem to receive full sized udp
encapsulated appletalk packets from the ethernet.
 Analysis: RBSZ does not account for udp encapsulation data (e.g.
ETHER_HEADERS).
 Solution: Increase RBSZ by ETHER_HEADERS.  In addition, note that in
pbuf, only MAXDATA (630) bytes are available in the data portion of
pbuf.  To account for this, we must start the pbuf offset back
ETHER_HEADERS size (e.g. start reading data into header portion of
pbuf) in ieframein.

An alternative analysis is to consider MAXDATA undersized at 630 bytes
and bump it to 645 bytes.  Unfortunately, this requires we recompile
"lap.s" which is in PROM on the Kinetics box.  (It isn't even clear
that we really would want to do this).

Two files need to be modified to correct this problem: ie.h and ie.c.
Context difference follow and can be applied using patch or by hand.

Bill Schilit and Charlie C. Kim
Columbia University

------ie.c.diff------
*** /tmp/,RCSt1006968	Mon Dec  8 19:12:59 1986
--- ie.c	Mon Dec  8 19:12:50 1986
***************
*** 7,20 ****
   *  (c) 1986, Kinetics, Inc.
   *  May be used but not sold without permission.
   *
!  *  $Header: ie.c,v 1.1 86/12/08 12:50:25 bill Exp $
   */
  
  #include "gw.h"
  #include "fp/pbuf.h"
- #include "ie.h"
  #include "ether.h"
  #include "ab.h"
  #include "fp/cmdmacro.h"
  
  extern char broadcastaddr[];
--- 7,21 ----
   *  (c) 1986, Kinetics, Inc.
   *  May be used but not sold without permission.
   *
!  *  $Header: ie.c,v 1.4 86/12/08 19:12:41 cck Exp $
   */
  
  #include "gw.h"
  #include "fp/pbuf.h"
  #include "ether.h"
  #include "ab.h"
+ #include "inet.h"
+ #include "ie.h"
  #include "fp/cmdmacro.h"
  
  extern char broadcastaddr[];
***************
*** 291,299 ****
  		/* get a buffer from the free list */
  		K_PGET(PT_ENET,pp);
  
! 		free = MAXDATA;
  		if (pp)
! 			pp->p_off = cp = pp->p_data;
  		for (rbdp = OTOA(struct r_bd *, rfdp->fd_rbd) ;
  		     rbdp->rbd.bd_count & SWAB(BD_F);
  		     rbdp = OTOA(struct r_bd *, rbdp->rbd.bd_next)) {
--- 292,300 ----
  		/* get a buffer from the free list */
  		K_PGET(PT_ENET,pp);
  
! 		free = MAXDATA + ETHER_HEADERS;
  		if (pp)
! 			pp->p_off = cp = (pp->p_data - ETHER_HEADERS);
  		for (rbdp = OTOA(struct r_bd *, rfdp->fd_rbd) ;
  		     rbdp->rbd.bd_count & SWAB(BD_F);
  		     rbdp = OTOA(struct r_bd *, rbdp->rbd.bd_next)) {
***************
*** 327,333 ****
  #endif	STATS
  		if (pp) {
  			K_SPLIMP(&pri);
! 			pp->p_len = MAXDATA - free;
  			p_if(pp) = &ifie;
  			/* enqueue a buffer to the rec'd packet queue */
  			K_PENQNP(pq,pp);
--- 328,334 ----
  #endif	STATS
  		if (pp) {
  			K_SPLIMP(&pri);
! 			pp->p_len = (MAXDATA+ETHER_HEADERS) - free;
  			p_if(pp) = &ifie;
  			/* enqueue a buffer to the rec'd packet queue */
  			K_PENQNP(pq,pp);
***************
*** 356,363 ****
--- 357,370 ----
  	K_PDEQNP(sendq,p);
  
  	bcopy(p->p_off, &tbd[0].t_buf[0], p->p_len);
+ #ifdef notdef
  	if (p->p_len < 64)
  		p->p_len = 64;
+ #else
+ 	/* shouldn't count crc bytes */
+ 	if (p->p_len < 60)
+ 		p->p_len = 60;
+ #endif
  	tbd[0].tbd.bd_count = SWAB(p->p_len | BD_EOF);
  
  	/* put the buffer back on the free list */



------------------------ 30 -----------------------
------ie.h.diff------
*** /tmp/,RCSt1005763	Mon Dec  8 18:57:35 1986
--- ie.h	Mon Dec  8 18:55:52 1986
***************
*** 7,13 ****
   *  (c) 1986, Kinetics, Inc.
   *  May be used but not sold without permission.
   *
!  *  $Header: ie.h,v 1.1 86/12/08 13:54:48 cck Exp $
   */
  
  /*
--- 7,13 ----
   *  (c) 1986, Kinetics, Inc.
   *  May be used but not sold without permission.
   *
!  *  $Header: ie.h,v 1.2 86/12/08 18:55:47 cck Exp $
   */
  
  /*
***************
*** 48,56 ****
--- 48,70 ----
  #define	BD_EL		0x8000	/* end of list */
  
  /*
+  * ETHER_HEADERS defines the length of ethernet header plus ip header plus
+  *  udp header for ip encapsulated packets.  Theoretically, pkts can't
+  *  be any bigger anyway.
+  *
+ */
+ #define ETHER_HEADERS (sizeof(struct ip)+sizeof(struct udp)+ \
+ 		       sizeof(struct ether_header))
+ 
+ /*
   * transmit buffer
   */
+ #ifdef notdef
  #define	TBSZ		MAXDATA
+ #else
+ /* must also account for ip data */
+ # define TBSZ (MAXDATA+ETHER_HEADERS)
+ #endif
  struct t_bd {
  	struct bd tbd;		/* the buffer descriptor */
  	char t_buf[TBSZ];	/* the transmit data */
***************
*** 59,65 ****
--- 73,84 ----
  /*
   * receive buffer
   */
+ #ifdef notdef
  #define	RBSZ		640	/* receive buffer size */
+ #else
+ /* must also account for ip data */
+ #define RBSZ (MAXDATA+ETHER_HEADERS)
+ #endif
  struct r_bd {
  	struct bd rbd;		/* the buffer descriptor */
  	char r_buf[RBSZ];	/* the received data */
------------------------ 30 -----------------------

cck%cunixc@COLUMBIA.EDU.UUCP (12/09/86)

Oh, I should also mention that one diff to ie.c makes the minimum
ethernet packet 60 bytes vs. 64 bytes.  Sometimes people put 64 in to
account for the CRC bytes, but this isn't right with the 286
controller (well, changing this to 60 makes it do the right thing -
send out 60 bytes min. sized pkts - in particular arp).

Charlie C. Kim
User Services Group
Columbia University