-/* on entry, a received frame is in ppp->rbuf.bufr
- check it and dispose as appropriate */
-
-static void ppp_doframe_lower (struct ppp *ppp, u_char *data, int len)
-{
- u_short proto;
- int count = len;
- ppp_proto_type *proto_ptr;
-/*
- * Ignore empty frames
- */
- if (count <= 0)
- return;
-/*
- * Count the frame and print it
- */
- ++ppp->stats.ppp_ipackets;
- if (ppp->flags & SC_LOG_INPKT)
- ppp_print_buffer ("receive frame", data, count);
-/*
- * Ignore the leading ADDRESS and CONTROL fields in the frame.
- */
- if ((data[0] == PPP_ALLSTATIONS) && (data[1] == PPP_UI)) {
- data += 2;
- count -= 2;
- }
-/*
- * Obtain the protocol from the frame
- */
- proto = (u_short) *data++;
- if (proto & 1)
- count--;
- else {
- proto = (proto << 8) | (u_short) *data++;
- count -= 2;
- }
-/*
- * Find the procedure to handle this protocol. The last one is marked
- * as a protocol 0 which is the 'catch-all' to feed it to the pppd daemon.
- */
- proto_ptr = proto_list;
- while (proto_ptr->proto != 0 && proto_ptr->proto != proto)
- ++proto_ptr;
-/*
- * Update the appropriate statistic counter.
- */
- if ((*proto_ptr->func) (ppp, proto, data, count))
- ppp->stats.ppp_ioctects += len;
- else
- ++ppp->stats.ppp_discards;
-}
-
-/* on entry, a received frame is in ppp->rbuf.bufr
- check it and dispose as appropriate */
-
-static int
-ppp_doframe (struct ppp *ppp)
-{
- u_char *data = buf_base (ppp->rbuf);
- int count = ppp->rbuf->count;
-#ifdef PPP_COMPRESS
- int proto;
- int new_count;
- u_char *new_data;
-#endif
-/*
- * If there is a pending error from the receiver then log it and discard
- * the damaged frame.
- */
- if (ppp->toss) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp_toss: tossing frame, reason = %d\n",
- ppp->toss);
- ppp->stats.ppp_ierrors++;
- return 0;
- }
-/*
- * An empty frame is ignored. This occurs if the FLAG sequence precedes and
- * follows each frame.
- */
- if (count == 0)
- return 1;
-/*
- * Generate an error if the frame is too small.
- */
- if (count < PPP_HARD_HDR_LEN) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp: got runt ppp frame, %d chars\n", count);
- slhc_toss (ppp->slcomp);
- ppp->stats.ppp_ierrors++;
- return 1;
- }
-/*
- * Verify the CRC of the frame and discard the CRC characters from the
- * end of the buffer.
- */
- if (ppp->rbuf->fcs != PPP_GOODFCS) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_WARNING
- "ppp: frame with bad fcs, excess = %x\n",
- ppp->rbuf->fcs ^ PPP_GOODFCS);
- ppp->stats.ppp_ierrors++;
- return 0;
- }
- count -= 2; /* ignore the fcs characters */
-
-#ifdef PPP_COMPRESS
- proto = PPP_PROTOCOL (data);
-/*
- * Process the active decompressor.
- */
- if ((ppp->sc_rc_state != (void *) 0) &&
- ((ppp->flags & SC_DECOMP_RUN) == 0)) {
-/*
- * If the frame is compressed then decompress it.
- */
- if (((ppp->flags & (SC_DC_FERROR | SC_DC_ERROR)) == 0) &&
- (proto == PPP_COMP)) {
- new_data = kmalloc (ppp->mru + 4, GFP_ATOMIC);
- if (new_data == NULL) {
- if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp_doframe: no memory\n");
- slhc_toss (ppp->slcomp);
- (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state,
- data,
- count);
- return 1;
- }
-/*
- * Decompress the frame
- */
- new_count = bsd_decompress (ppp->sc_rc_state,
- data,
- count,
- new_data,
- ppp->mru + 4);
-
- switch (new_count) {
- default:
- ppp_doframe_lower (ppp, new_data, new_count);
- kfree (new_data);
- return 1;
-
- case DECOMP_OK:
- break;
-
- case DECOMP_ERROR:
- ppp->flags |= SC_DC_ERROR;
- break;
-
- case DECOMP_FATALERROR:
- ppp->flags |= SC_DC_FERROR;
- break;
- }
-/*
- * Log the error condition and discard the frame.
- */
- if (ppp->flags & SC_DEBUG)
- printk (KERN_ERR
- "ppp_proto_comp: "
- "decompress err %d\n", new_count);
- kfree (new_data);
- slhc_toss (ppp->slcomp);
- return 1;
- }
-/*
- * The frame is not special. Pass it through the decompressor without
- * actually decompressing the data
- */
- (*ppp->sc_rcomp->incomp) (ppp->sc_rc_state,
- data,
- count);
- }
-#endif
-/*
- * Process the uncompressed frame.
- */
- ppp_doframe_lower (ppp, data, count);
- return 1;
-}
-