📄 hd_input.c
字号:
/* * Copyright (c) University of British Columbia, 1984 * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Laboratory for Computation Vision and the Computer Science Department * of the University of British Columbia. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)hd_input.c 8.1 (Berkeley) 6/10/93 */#include <sys/param.h>#include <sys/systm.h>#include <sys/mbuf.h>#include <sys/domain.h>#include <sys/socket.h>#include <sys/protosw.h>#include <sys/errno.h>#include <sys/time.h>#include <sys/kernel.h>#include <net/if.h>#include <netccitt/hdlc.h>#include <netccitt/hd_var.h>#include <netccitt/x25.h>static frame_reject();static rej_routine();static free_iframes();/* * HDLC INPUT INTERFACE * * This routine is called when the HDLC physical device has * completed reading a frame. */hdintr (){ register struct mbuf *m; register struct hdcb *hdp; register struct ifnet *ifp; register int s; static struct ifnet *lastifp; static struct hdcb *lasthdp; for (;;) { s = splimp (); IF_DEQUEUE (&hdintrq, m); splx (s); if (m == 0) break; if (m->m_len < HDHEADERLN) { printf ("hdintr: packet too short (len=%d)\n", m->m_len); m_freem (m); continue; } if ((m->m_flags & M_PKTHDR) == 0) panic("hdintr"); ifp = m->m_pkthdr.rcvif; /* * look up the appropriate hdlc control block */ if (ifp == lastifp) hdp = lasthdp; else { for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) if (hdp->hd_ifp == ifp) break; if (hdp == 0) { printf ("hdintr: unknown interface %x\n", ifp); m_freem (m); continue; } lastifp = ifp; lasthdp = hdp; } /* Process_rxframe returns FALSE if the frame was NOT queued for the next higher layers. */ if (process_rxframe (hdp, m) == FALSE) m_freem (m); }}process_rxframe (hdp, fbuf)register struct hdcb *hdp;register struct mbuf *fbuf;{ register int queued = FALSE, frametype, pf; register struct Hdlc_frame *frame; frame = mtod (fbuf, struct Hdlc_frame *); pf = ((struct Hdlc_iframe *) frame) -> pf; hd_trace (hdp, RX, frame); if (frame -> address != ADDRESS_A && frame -> address != ADDRESS_B) return (queued); switch ((frametype = hd_decode (hdp, frame)) + hdp->hd_state) { case DM + DISC_SENT: case UA + DISC_SENT: /* * Link now closed. Leave timer running * so hd_timer() can periodically check the * status of interface driver flag bit IFF_UP. */ hdp->hd_state = DISCONNECTED; break; case DM + INIT: case UA + INIT: /* * This is a non-standard state change needed for DCEs * that do dynamic link selection. We can't go into the * usual "SEND DM" state because a DM is a SARM in LAP. */ hd_writeinternal (hdp, SABM, POLLOFF); hdp->hd_state = SABM_SENT; SET_TIMER (hdp); break; case SABM + DM_SENT: case SABM + WAIT_SABM: hd_writeinternal (hdp, UA, pf); case UA + SABM_SENT: case UA + WAIT_UA: KILL_TIMER (hdp); hd_initvars (hdp); hdp->hd_state = ABM; hd_message (hdp, "Link level operational"); /* Notify the packet level - to send RESTART. */ (void) pk_ctlinput (PRC_LINKUP, hdp->hd_pkp); break; case SABM + SABM_SENT: /* Got a SABM collision. Acknowledge the remote's SABM via UA but still wait for UA. */ hd_writeinternal (hdp, UA, pf); break; case SABM + ABM: /* Request to reset the link from the remote. */ KILL_TIMER (hdp); hd_message (hdp, "Link reset");#ifdef HDLCDEBUG hd_dumptrace (hdp);#endif hd_flush (hdp->hd_ifp); hd_writeinternal (hdp, UA, pf); hd_initvars (hdp); (void) pk_ctlinput (PRC_LINKRESET, hdp->hd_pkp); hdp->hd_resets++; break; case SABM + WAIT_UA: hd_writeinternal (hdp, UA, pf); break; case DM + ABM: hd_message (hdp, "DM received: link down");#ifdef HDLCDEBUG hd_dumptrace (hdp);#endif (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); hd_flush (hdp->hd_ifp); case DM + DM_SENT: case DM + WAIT_SABM: case DM + WAIT_UA: hd_writeinternal (hdp, SABM, pf); hdp->hd_state = SABM_SENT; SET_TIMER (hdp); break; case DISC + INIT: case DISC + DM_SENT: case DISC + SABM_SENT: /* Note: This is a non-standard state change. */ hd_writeinternal (hdp, UA, pf); hd_writeinternal (hdp, SABM, POLLOFF); hdp->hd_state = SABM_SENT; SET_TIMER (hdp); break; case DISC + WAIT_UA: hd_writeinternal (hdp, DM, pf); SET_TIMER (hdp); hdp->hd_state = DM_SENT; break; case DISC + ABM: hd_message (hdp, "DISC received: link down"); (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); case DISC + WAIT_SABM: hd_writeinternal (hdp, UA, pf); hdp->hd_state = DM_SENT; SET_TIMER (hdp); break; case UA + ABM: hd_message (hdp, "UA received: link down"); (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); case UA + WAIT_SABM: hd_writeinternal (hdp, DM, pf); hdp->hd_state = DM_SENT; SET_TIMER (hdp); break; case FRMR + DM_SENT: hd_writeinternal (hdp, SABM, pf); hdp->hd_state = SABM_SENT; SET_TIMER (hdp); break; case FRMR + WAIT_SABM: hd_writeinternal (hdp, DM, pf); hdp->hd_state = DM_SENT; SET_TIMER (hdp); break; case FRMR + ABM: hd_message (hdp, "FRMR received: link down"); (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);#ifdef HDLCDEBUG hd_dumptrace (hdp);#endif hd_flush (hdp->hd_ifp); hd_writeinternal (hdp, SABM, pf); hdp->hd_state = WAIT_UA; SET_TIMER (hdp); break; case RR + ABM: case RNR + ABM: case REJ + ABM: process_sframe (hdp, (struct Hdlc_sframe *)frame, frametype); break; case IFRAME + ABM: queued = process_iframe (hdp, fbuf, (struct Hdlc_iframe *)frame); break; case IFRAME + SABM_SENT: case RR + SABM_SENT: case RNR + SABM_SENT: case REJ + SABM_SENT: hd_writeinternal (hdp, DM, POLLON); hdp->hd_state = DM_SENT; SET_TIMER (hdp); break; case IFRAME + WAIT_SABM: case RR + WAIT_SABM: case RNR + WAIT_SABM: case REJ + WAIT_SABM: hd_writeinternal (hdp, FRMR, POLLOFF); SET_TIMER (hdp); break; case ILLEGAL + SABM_SENT: hdp->hd_unknown++; hd_writeinternal (hdp, DM, POLLOFF); hdp->hd_state = DM_SENT; SET_TIMER (hdp); break; case ILLEGAL + ABM: hd_message (hdp, "Unknown frame received: link down"); (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); case ILLEGAL + WAIT_SABM: hdp->hd_unknown++;#ifdef HDLCDEBUG hd_dumptrace (hdp);#endif hd_writeinternal (hdp, FRMR, POLLOFF); hdp->hd_state = WAIT_SABM; SET_TIMER (hdp); break; } return (queued);}process_iframe (hdp, fbuf, frame)register struct hdcb *hdp;struct mbuf *fbuf;register struct Hdlc_iframe *frame;{ register int nr = frame -> nr, ns = frame -> ns, pf = frame -> pf; register int queued = FALSE; /* * Validate the iframe's N(R) value. It's N(R) value must be in * sync with our V(S) value and our "last received nr". */ if (valid_nr (hdp, nr, FALSE) == FALSE) { frame_reject (hdp, Z, frame); return (queued); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -