+ vvtracehdr("vi", vv);
+ resid = addr->vviwc;
+ if (resid)
+ resid |= 0176000; /* ugly!!!! */
+ len = (((sizeof (struct vv_header) + VVMRU) >> 1) + resid) << 1;
+ len -= sizeof(struct vv_header);
+ if (len > VVMRU || len <= 0) {
+ if (vv_logreaderrors && vs->vs_if.if_flags & IFF_DEBUG)
+ printf("vv%d: len too big, len = %d, vvicsr = %b\n",
+ unit, len, 0xffff&(addr->vvicsr), VV_IBITS);
+ goto dropit;
+ }
+#define vvdataaddr(vv, off, type) ((type)(((caddr_t)((vv)+1)+(off))))
+ if (vv->vh_type >= RING_IPTrailer &&
+ vv->vh_type < RING_IPTrailer+RING_IPNTrailer) {
+ off = (vv->vh_type - RING_IPTrailer) * 512;
+ if (off > VVMTU) {
+ if (vv_logreaderrors && vs->vs_if.if_flags & IFF_DEBUG)
+ printf("vv%d: VVMTU, off = %d, vvicsr = %b\n",
+ unit, off, 0xffff&(addr->vvicsr), VV_IBITS);
+ goto dropit;
+ }
+ vv->vh_type = *vvdataaddr(vv, off, u_short *);
+ resid = *(vvdataaddr(vv, off+2, u_short *));
+ if (off + resid > len) {
+ if (vv_logreaderrors && vs->vs_if.if_flags & IFF_DEBUG)
+ printf(
+ "vv%d: off = %d, resid = %d, vvicsr = %b\n",
+ unit, off, resid,
+ 0xffff&(addr->vvicsr), VV_IBITS);
+ goto dropit;
+ }
+ len = off + resid;
+ } else
+ off = 0;
+ if (len == 0) {
+ if (vv_logreaderrors && vs->vs_if.if_flags & IFF_DEBUG)
+ printf("vv%d: len is zero, vvicsr = %b\n", unit,
+ 0xffff&(addr->vvicsr), VV_IBITS);
+ goto dropit;
+ }
+ m = if_rubaget(&vs->vs_ifuba, len, off);
+ if (m == NULL) {
+ if (vv_logreaderrors && vs->vs_if.if_flags & IFF_DEBUG)
+ printf("vv%d: if_rubaget failed, vvicsr = %b\n", unit,
+ 0xffff&(addr->vvicsr), VV_IBITS);
+ goto dropit;
+ }
+ if (off) {
+ m->m_off += 2 * sizeof(u_short);
+ m->m_len -= 2 * sizeof(u_short);
+ }
+
+ /* Keep track of source address of this packet */
+ vs->vs_lastr = vv->vh_shost;