📄 dli_input.c
字号:
if ( loop_msg[loop_sc++] != DLI_LBACK_FWD || loop_msg[loop_sc++] != NULL ) { return(m); } CALL_TO_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity); error = rcv->rcv_ifp->if_ioctl(rcv->rcv_ifp, SIOCRPHYSADDR, (caddr_t)&ifd); RETURN_FROM_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity); if ( (error) || (bcmp(ifd.current_pa, rcv->rcv_hdr.rcv_ether.ether_shost, DLI_EADDRSIZE) == 0) ) { m_freem(m); return(NULL); } /* * log passive loopback initiated event if not already given for * present node. */ timer_active = NULL; smp_lock(&lk_dli, LK_RETRY); for( i = 0; i < DLI_MAX_LBTIMR; i++) { if ( (lback_timers[i].tval != 0) && bcmp(rcv->rcv_hdr.rcv_ether.ether_shost, lback_timers[i].actv_addr, DLI_EADDRSIZE) == NULL ) { lback_timers[i].tval = DLI_LBEVL_WAIT; timer_active = 1; break; } } if ( ! timer_active && establish_event( &rcv->rcv_hdr.rcv_ether, rcv ) ) { smp_unlock(&lk_dli); log_event(rcv->rcv_ifp, DLI_EVLOP_LBINI); } else smp_unlock(&lk_dli); /* * forward loopback message. */ dst_addr.dli_family = AF_DLI; dst_addr.dli_substructype = DLI_ETHERNET; *(struct ether_pa *) dst_addr.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *) (loop_msg+loop_sc); dst_addr.choose_addr.dli_eaddr.dli_protype = rcv->rcv_hdr.rcv_ether.ether_type; loop_sc += (DLI_EADDRSIZE - sizeof(loop_sc)); INS16(loop_msg, loop_sc); CALL_TO_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity); rcv->rcv_ifp->if_output(rcv->rcv_ifp, m->m_next, &dst_addr); RETURN_FROM_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity); m_free(m); return(NULL);}/* * l o o p b a c k _ p t o p _ m s g * * This routine processes Point to Point loopback messages. * * Outputs: mbuf chain given to driver if message to be forwared. * returns NULL if message looped, otherwise mbuf pointer returned. * * Inputs: m = mbuf chain containing packet. * mop = 1 if MOP, 0 if not MOP mode * rcv = pointer to data link header structure. */struct mbuf *loopback_ptop_msg( m, mop, rcv )register struct mbuf *m;int mop;register struct dli_recv *rcv;{ u_char *mop_code; u_short i; int saveaffinity; /* for nonsym drivers. 8.18.88.us */ struct sockaddr_dl dst_addr; /* * make sure device is currently looping; if so, reset loopback timer; * if not, packet belongs to a user. */ smp_lock(&lk_dli, LK_RETRY); for( i = 0; i < DLI_MAX_LBTIMR; i++) { if ( (lback_timers[i].tval != 0) && (rcv->rcv_ifp == lback_timers[i].ifp) ) { lback_timers[i].tval = DLI_LBEVL_POP; break; } } smp_unlock(&lk_dli); if ( i == DLI_MAX_LBTIMR && ! mop ) { return(m); } /* * pull MOP code into second mbuf if not already there */ if ( ! pull_header(m, 1) ) { return(NULL); } else if ( *(mop_code = mtod(m->m_next, u_char *)) == DLI_LBACK_LOOP ) { /* free first mbuf which has no relevant data */ m = m_free(m); /* * forward loopback message. */ dst_addr.dli_family = AF_DLI; dst_addr.dli_substructype = DLI_POINTOPOINT; *mop_code = (u_char) DLI_LBACK_LOOPED; CALL_TO_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity); rcv->rcv_ifp->if_output(rcv->rcv_ifp, m, &dst_addr); RETURN_FROM_NONSMP_DRIVER( (*rcv->rcv_ifp), saveaffinity); return(NULL); } else { return(m); }}/* * l o g _ e v e n t * * This subroutine logs a passive loopback message to evl. * * Outputs: None. * * Inputs: None. */log_event(ifp, evl_op)register struct ifnet *ifp;u_char evl_op;{ struct protosw *evl_ptr; static struct event events[DLI_MAXPROC];#define event events[CURRENT_CPUDATA->cpu_num] register int i; /* * log event only if evl is present */ if ( ! (evl_ptr = pffindproto( AF_DECnet, DNPROTO_EVR )) ) { return; } /* * init event structure. */ event.e_class = DLI_LBEVL_CLASS; event.e_type = DLI_LBEVL_TYPE; event.e_ent_type = DLI_LBEVL_ETYPE; i = fetch_decnet_devname( ifp, event.e_ent_id ); event.e_ent_id[i++] = ifp->if_unit + '0'; event.e_ent_id[i] = NULL; event.e_data[0] = DLI_EVLOP_CODE; event.e_data[1] = NULL; event.e_data[2] = DLI_EVLOP_DESC; event.e_data[3] = evl_op; event.e_data_len = 4; /* * log event */ (evl_ptr->pr_input)( &event ); return;#undef event}/* * s c m p * * This subroutine compares two strings. * * Outputs: 0 if strings unequal, 1 if strings equal. * * Inputs: s1, s2 = pointers to strings to be compared. */scmp(s1, s2)register char *s1, *s2;{ while ( *s1 == *s2++ ) if ( *s1++ == NULL ) return(1); return(0);}/* * p u l l _ h e a d e r * * This routine pulls up a header into the second mbuf. * NOTE: first mbuf contains info placed by dli_ifinput. * * Outputs: 1 if successful, 0 if failure. * * Inputs: m = mbuf chain containing packet. * hsiz = size of header to be pulled up. */pull_header( m, hsiz )register struct mbuf *m;register short hsiz;{ register int i = 0; register struct mbuf *tm = m->m_next; if ( hsiz <= m->m_next->m_len ) return(1); while ( tm ) { i += tm->m_len; tm = tm->m_next; } if ( (m->m_next = m_pullup(m->m_next, ((i < hsiz) ? i : hsiz))) == NULL ) { m_freem(m); return(NULL); } return(1);}/* * e s t a b l i s h _ e v e n t * * This routine sets up a loopback event in the * loopback timer table. * * Note: DLI protocol lock must be asserted before this * routine is called. * * Inputs: header = address of packet header. * (zeroed out for point to point) * rcv = pointer to data link header structure. * * Outputs: 1 if success, otherwise NULL. */establish_event( eh, rcv )register struct ether_header *eh;register struct dli_recv *rcv;{ int i = -1; while (lback_timers[++i].tval != 0 && i < DLI_MAX_LBTIMR) ; if ( i < DLI_MAX_LBTIMR ) { lback_timers[i].tval = DLI_LBEVL_WAIT; lback_timers[i].ifp = rcv->rcv_ifp; *(struct ether_pa *) lback_timers[i].actv_addr = *(struct ether_pa *) eh->ether_shost; return(1); } else { return(0); }}/* * f e t c h _ d e c n e t _ d e v n a m e * * This routine translates the ULTRIX device name into the DECnet * device name. * * Inputs: dn_devname = pointer where DECnet device name is to * placed. * * Outputs: dn_devname = DECnet device name. * * Returns: number of characters in device name. * */fetch_decnet_devname( ifp, dn_devname )register struct ifnet *ifp;register u_char *dn_devname;{ register int i = 0; if ( scmp(ifp->if_name, "qe") ) { bcopy( "QNA-", dn_devname, (i = 4) ); } else if ( scmp(ifp->if_name, "de") ) { bcopy( "UNA-", dn_devname, (i = 4) ); } else if ( scmp(ifp->if_name, "ni") ) { bcopy( "BNT-", dn_devname, (i = 4) ); } else if ( scmp(ifp->if_name, "xna") ) { bcopy( "XNA-", dn_devname, (i = 4) ); } else if ( scmp(ifp->if_name, "ln") ) { bcopy( "SVA-", dn_devname, (i = 4) ); } else if ( scmp(ifp->if_name, "dmc") ) { bcopy( "DMC-", dn_devname, (i = 4) ); } else if ( scmp(ifp->if_name, "dmv") ) { bcopy( "DMV-", dn_devname, (i = 4) ); } else { i = 0; while ( ifp->if_name[i] ) { dn_devname[i] = ifp->if_name[i]; if ( dn_devname[i] >= 'a' ) dn_devname[i] = dn_devname[i] - ('a' - 'A'); i++; } dn_devname[i++] = '-'; } return(i);}#ifdef notdef/* * m b u f _ l e n * * Compute the number of bytes in a (non-empty) MBUF chain. * * Returns: The number of bytes in the chain. * * Inputs: * m = Pointer to the MBUF chain. */mbuf_len( m )register struct mbuf *m;{ register struct mbuf *m0 = m; register int len = 0; while( m0 ) { len += m0->m_len; m0 = m0->m_next; } return (len);}#endif/* * d l i _ p r o c _ r e q s y s i d * * This routine is called to process requests for sysid * If this is a request for a sysid from a node * find the matching sysid_to struct to tx on * copy requestor node address to the target * transmit the sysid * * Outputs: None. * * Inputs: pointer to mbuf chain from driver * pointer to dli_recv structure. * * Version History: * 1.0 JA * */dli_proc_reqsysid(m, recv)struct mbuf *m;struct dli_recv *recv;{ register int i, nsiz = 0; u_short msglen; /* * If to multicast, make sure its the correct one. */ if ( recv->rcv_hdr.rcv_ether.ether_dhost[0] & MCASTADDR ) if (bcmp( recv->rcv_hdr.rcv_ether.ether_dhost, sysid_mcast, DLI_EADDRSIZE) != 0) { m_freem(m); return; } msglen = EXT16(mtod(m->m_next, u_char *)); if ( msglen < 4 ) { m_freem(m); return; } while( *(((u_char *) recv->rcv_ifp->if_name)+nsiz) != NULL ) nsiz++; i = -1; while ( mop_dev_code[++i].devtyp ) if( bcmp(mop_dev_code[i].devnam, recv->rcv_ifp->if_name, nsiz) == 0 ) { smp_lock(&lk_dli, LK_RETRY); *(struct ether_pa *)sysid_dst.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *)recv->rcv_hdr.rcv_ether.ether_shost; dli_snd_sysid(recv->rcv_ifp, EXT16((mtod(m->m_next, u_char *) + 4)), mop_dev_code[i].devtyp); *(struct ether_pa *)sysid_dst.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *) sysid_mcast; smp_unlock(&lk_dli); break; } m_freem(m);}/* * d l i _ p r o c _ r e q c t r s * * This routine is called to process requests for data link counters * * Outputs: None. * * Inputs: pointer to mbuf chain from driver * pointer to dli_recv structure. * * Version History: * 1.0 JA * */dli_proc_reqctrs(m, recv)struct mbuf *m;struct dli_recv *recv;{ struct ctrreq ctrs; u_short receipt, msglen; register u_char *bmsg, *msg = mtod(m, u_char *); int saveaffinity; /* for nonsym drivers. 8.18.88.us */ int error; struct sockaddr_dl dst_addr; struct mbuf *recv_hdr; /* * If to multicast, make sure its the correct one. */ if ( recv->rcv_hdr.rcv_ether.ether_dhost[0] & MCASTADDR ) if (bcmp(recv->rcv_hdr.rcv_ether.ether_dhost, sysid_mcast, DLI_EADDRSIZE) != 0) { m_freem(m); return; } /* * pull MOP message into second mbuf if not already there */ if ( ! pull_header(m, 5) ) { return; } msglen = EXT16(mtod(m->m_next, u_short *)); if ( msglen < 3 ) { m_freem(m); return; } /* * Save receipt from message and then delete remainder of message, * saving one mbuf for transmission of counters. */ receipt = EXT16((mtod(m->m_next, u_char *) + sizeof(u_short) + 1)); m_freem(m->m_next); m->m_next = NULL; CALL_TO_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity); error = ( recv->rcv_ifp->if_ioctl(recv->rcv_ifp, SIOCRDCTRS, (caddr_t)&ctrs)); RETURN_FROM_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity); if ( error ) { m_freem(m); return; } /* * place counters in mbuf and transmit */ bmsg = msg; msg += sizeof(u_short); *msg++ = DLI_CTRS; INS16(msg, receipt); msg += sizeof(u_short); switch ( ctrs.ctr_type ) { case CTR_ETHER: /* ethernet device - format counters */ INS16(msg, ctrs.ctr_ether.est_seconds); msg += sizeof(ctrs.ctr_ether.est_seconds); INS32(msg, ctrs.ctr_ether.est_bytercvd); msg += sizeof(ctrs.ctr_ether.est_bytercvd); INS32(msg, ctrs.ctr_ether.est_bytesent); msg += sizeof(ctrs.ctr_ether.est_bytesent); INS32(msg, ctrs.ctr_ether.est_blokrcvd); msg += sizeof(ctrs.ctr_ether.est_blokrcvd); INS32(msg, ctrs.ctr_ether.est_bloksent); msg += sizeof(ctrs.ctr_ether.est_bloksent); INS32(msg, ctrs.ctr_ether.est_mbytercvd); msg += sizeof(ctrs.ctr_ether.est_mbytercvd); INS32(msg, ctrs.ctr_ether.est_mblokrcvd); msg += sizeof(ctrs.ctr_ether.est_mblokrcvd); INS32(msg, ctrs.ctr_ether.est_deferred); msg += sizeof(ctrs.ctr_ether.est_deferred); INS32(msg, ctrs.ctr_ether.est_single); msg += sizeof(ctrs.ctr_ether.est_single); INS32(msg, ctrs.ctr_ether.est_multiple); msg += sizeof(ctrs.ctr_ether.est_multiple); INS16(msg, ctrs.ctr_ether.est_sendfail); msg += sizeof(ctrs.ctr_ether.est_sendfail); INS16(msg, ctrs.ctr_ether.est_sendfail_bm); msg += sizeof(ctrs.ctr_ether.est_sendfail_bm); INS16(msg, ctrs.ctr_ether.est_recvfail); msg += sizeof(ctrs.ctr_ether.est_recvfail); INS16(msg, ctrs.ctr_ether.est_recvfail_bm); msg += sizeof(ctrs.ctr_ether.est_recvfail_bm); INS16(msg, ctrs.ctr_ether.est_unrecog); msg += sizeof(ctrs.ctr_ether.est_unrecog); INS16(msg, ctrs.ctr_ether.est_overrun); msg += sizeof(ctrs.ctr_ether.est_overrun); INS16(msg, ctrs.ctr_ether.est_sysbuf); msg += sizeof(ctrs.ctr_ether.est_sysbuf); INS16(msg, ctrs.ctr_ether.est_userbuf); msg += sizeof(ctrs.ctr_ether.est_userbuf); /* * Place message size at beginning, create dest addr, * and transmit */ m->m_len = (short) (msg - bmsg); INS16(bmsg, (u_short) (m->m_len - sizeof(u_short))); dst_addr.dli_family = AF_DLI; dst_addr.dli_substructype = DLI_ETHERNET; *(struct ether_pa *) dst_addr.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *) recv->rcv_hdr.rcv_ether.ether_shost; dst_addr.choose_addr.dli_eaddr.dli_protype = recv->rcv_hdr.rcv_ether.ether_type; break; case CTR_DDCMP: /* point to point device */ default: m_freem(m); return; break; } CALL_TO_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity); recv->rcv_ifp->if_output(recv->rcv_ifp, m, &dst_addr); RETURN_FROM_NONSMP_DRIVER( (*recv->rcv_ifp), saveaffinity); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -