/*
 * Calculate a new FCS given the current FCS and the new data.
 */
u_short
pppfcs(u_short fcs, u_char *cp, int len)
{
    while (len--)
	fcs = PPP_FCS(fcs, *cp++);
    return (fcs);
}
Esempio n. 2
0
/*
 * loop_chars - process characters received from the loopback.
 * Calls loop_frame when a complete frame has been accumulated.
 * Return value is 1 if we need to bring up the link, 0 otherwise.
 */
int
loop_chars(
    unsigned char *p,
    int n)
{
    int c, rv;

    rv = 0;
    for (; n > 0; --n) {
	c = *p++;
	if (c == PPP_FLAG) {
	    if (!escape_flag && !flush_flag
		&& framelen > 2 && fcs == PPP_GOODFCS) {
		framelen -= 2;
		if (loop_frame(frame, framelen))
		    rv = 1;
	    }
	    framelen = 0;
	    flush_flag = 0;
	    escape_flag = 0;
	    fcs = PPP_INITFCS;
	    continue;
	}
	if (flush_flag)
	    continue;
	if (escape_flag) {
	    c ^= PPP_TRANS;
	    escape_flag = 0;
	} else if (c == PPP_ESCAPE) {
	    escape_flag = 1;
	    continue;
	}
	if (framelen >= framemax) {
	    flush_flag = 1;
	    continue;
	}
	frame[framelen++] = c;
	fcs = PPP_FCS(fcs, c);
    }
    return rv;
}
Esempio n. 3
0
int check_frame(unsigned char *outbuf, int res)
{
	static int setup = 0;
	int x;
	unsigned short fcs = PPP_INITFCS;
	if (c < 1) {
		c = 1;
	}
	if (!setup) {
		c = outbuf[0];
		setup++;
	}
	for (x = 0; x < res; x++) {
		if (outbuf[x] != c && (x < res - 2)) {
			printf("(Error %d): Unexpected result, %d != %d, position %d %d bytes since last error.\n",
				   ++errors, outbuf[x], c, x, bytes);
			if (!x) {
				c = outbuf[0];
			}
			bytes = 0;
		} else {
			bytes++;
		}
		fcs = PPP_FCS(fcs, outbuf[x]);
	}
	if (fcs != PPP_GOODFCS) {
		printf("FCS Check failed :( (%04x != %04x)\n", fcs, PPP_GOODFCS);
	}
#if 0
	if (res != c) {
		printf("Res is %d, expected %d\n", res, c+2);
	}
#endif
	c = bit_next(c);
	return 0;
}
Esempio n. 4
0
/* Send a packet on the given connection. */
static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)
{
    int pd = (int)netif->state;
    u_short protocol = PPP_IP;
    PPPControl *pc = &pppControl[pd];
    u_int fcsOut = PPP_INITFCS;
    struct pbuf *headMB = NULL, *tailMB = NULL, *p;
    u_char c;

    (void)ipaddr;

    /* Validate parameters. */
    /* We let any protocol value go through - it can't hurt us
     * and the peer will just drop it if it's not accepting it. */
	if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {
        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",
                    pd, protocol, pb));
#if LINK_STATS
		lwip_stats.link.opterr++;
		lwip_stats.link.drop++;
#endif
		return ERR_ARG;
	}

    /* Check that the link is up. */
	if (lcp_phase[pd] == PHASE_DEAD) {
        PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd));
#if LINK_STATS
		lwip_stats.link.rterr++;
		lwip_stats.link.drop++;
#endif
		return ERR_RTE;
	}

    /* Grab an output buffer. */
	headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
    if (headMB == NULL) {
        PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd));
#if LINK_STATS
		lwip_stats.link.memerr++;
		lwip_stats.link.drop++;
#endif /* LINK_STATS */
        return ERR_MEM;
    }
        
#if VJ_SUPPORT > 0
    /* 
     * Attempt Van Jacobson header compression if VJ is configured and
     * this is an IP packet. 
     */
    if (protocol == PPP_IP && pc->vjEnabled) {
        switch (vj_compress_tcp(&pc->vjComp, pb)) {
        case TYPE_IP:
            /* No change...
            protocol = PPP_IP_PROTOCOL;
             */
            break;
        case TYPE_COMPRESSED_TCP:
            protocol = PPP_VJC_COMP;
            break;
        case TYPE_UNCOMPRESSED_TCP:
            protocol = PPP_VJC_UNCOMP;
            break;
        default:
            PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd));
#if LINK_STATS
			lwip_stats.link.proterr++;
			lwip_stats.link.drop++;
#endif
        	pbuf_free(headMB);
            return ERR_VAL;
        }
    }
#endif
        
    tailMB = headMB;
        
    /* Build the PPP header. */
    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)
        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
    pc->lastXMit = sys_jiffies();
    if (!pc->accomp) {
        fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);
        tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);
        fcsOut = PPP_FCS(fcsOut, PPP_UI);
        tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);
    }
    if (!pc->pcomp || protocol > 0xFF) {
        c = (protocol >> 8) & 0xFF;
        fcsOut = PPP_FCS(fcsOut, c);
        tailMB = pppAppend(c, tailMB, &pc->outACCM);
    }
Esempio n. 5
0
    if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG)
        tailMB = pppAppend(PPP_FLAG, tailMB, NULL);
    pc->lastXMit = sys_jiffies();
    if (!pc->accomp) {
        fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS);
        tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM);
        fcsOut = PPP_FCS(fcsOut, PPP_UI);
        tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM);
    }
    if (!pc->pcomp || protocol > 0xFF) {
        c = (protocol >> 8) & 0xFF;
        fcsOut = PPP_FCS(fcsOut, c);
        tailMB = pppAppend(c, tailMB, &pc->outACCM);
    }
    c = protocol & 0xFF;
    fcsOut = PPP_FCS(fcsOut, c);
    tailMB = pppAppend(c, tailMB, &pc->outACCM);
    
    /* Load packet. */
	for(p = pb; p; p = p->next) {
    	int n;
    	u_char *sPtr;

        sPtr = (u_char*)p->payload;
        n = p->len;
        while (n-- > 0) {
            c = *sPtr++;
            
            /* Update FCS before checking for special characters. */
            fcsOut = PPP_FCS(fcsOut, c);
            
Esempio n. 6
0
void
dumpppp(FILE *f)
{
    int c, n, k;
    int nb, nl, dn, proto, rv;
    char *dir, *q;
    unsigned char *p, *r, *endp;
    unsigned char *d;
    unsigned short fcs;
    struct pkt *pkt;

    spkt.cnt = rpkt.cnt = 0;
    spkt.esc = rpkt.esc = 0;
    while ((c = getc(f)) != EOF) {
	switch (c) {
	case 1:
	case 2:
	    if (reverse)
		c = 3 - c;
	    dir = c==1? "sent": "rcvd";
	    pkt = c==1? &spkt: &rpkt;
	    n = getc(f);
	    n = (n << 8) + getc(f);
	    *(c==1? &tot_sent: &tot_rcvd) += n;
	    for (; n > 0; --n) {
		c = getc(f);
		switch (c) {
		case EOF:
		    printf("\nEOF\n");
		    if (spkt.cnt > 0)
			printf("[%d bytes in incomplete send packet]\n",
			       spkt.cnt);
		    if (rpkt.cnt > 0)
			printf("[%d bytes in incomplete recv packet]\n",
			       rpkt.cnt);
		    exit(0);
		case '~':
		    if (pkt->cnt > 0) {
			q = dir;
			if (pkt->esc) {
			    printf("%s aborted packet:\n     ", dir);
			    q = "    ";
			}
			nb = pkt->cnt;
			p = pkt->buf;
			pkt->cnt = 0;
			pkt->esc = 0;
			if (nb <= 2) {
			    printf("%s short packet [%d bytes]:", q, nb);
			    for (k = 0; k < nb; ++k)
				printf(" %.2x", p[k]);
			    printf("\n");
			    break;
			}
			fcs = PPP_INITFCS;
			for (k = 0; k < nb; ++k)
			    fcs = PPP_FCS(fcs, p[k]);
			fcs &= 0xFFFF;
			nb -= 2;
			endp = p + nb;
			r = p;
			if (r[0] == 0xff && r[1] == 3)
			    r += 2;
			if ((r[0] & 1) == 0)
			    ++r;
			++r;
			if (endp - r > mru)
			    printf("     ERROR: length (%td) > MRU (%d)\n",
				   endp - r, mru);
			if (decompress && fcs == PPP_GOODFCS) {
			    /* See if this is a CCP or compressed packet */
			    d = dbuf;
			    r = p;
			    if (r[0] == 0xff && r[1] == 3) {
				*d++ = *r++;
				*d++ = *r++;
			    }
			    proto = r[0];
			    if ((proto & 1) == 0)
				proto = (proto << 8) + r[1];
			    if (proto == PPP_CCP) {
				handle_ccp(pkt, r + 2, endp - r - 2);
			    } else if (proto == PPP_COMP) {
				if ((pkt->flags & CCP_ISUP)
				    && (pkt->flags & CCP_DECOMP_RUN)
				    && pkt->state
				    && (pkt->flags & CCP_ERR) == 0) {
				    struct packet in, out, *outp;
				    in.buf = r;
				    in.len = endp - r;
				    out.buf = d;
				    outp = &out;
				    rv = pkt->comp->decompress(pkt->state, &in,
					&outp);
				    dn = outp->len;
				    d = outp->buf;
				    switch (rv) {
				    case DECOMP_OK:
					p = dbuf;
					nb = d + dn - p;
					if ((d[0] & 1) == 0)
					    --dn;
					--dn;
					if (dn > mru)
					    printf("     ERROR: decompressed length (%d) > MRU (%d)\n", dn, mru);
					break;
				    case DECOMP_ERROR:
					printf("     DECOMPRESSION ERROR\n");
					pkt->flags |= CCP_ERROR;
					break;
				    case DECOMP_FATALERROR:
					printf("     FATAL DECOMPRESSION ERROR\n");
					pkt->flags |= CCP_FATALERROR;
					break;
				    }
				}
			    } else if (pkt->state
				       && (pkt->flags & CCP_DECOMP_RUN)) {
				struct packet in;
				in.buf = r;
				in.len = endp - r;
				pkt->comp->incomp(pkt->state, &in);
			    }
			}
			do {
			    nl = nb < 16? nb: 16;
			    printf("%s ", q);
			    for (k = 0; k < nl; ++k)
				printf(" %.2x", p[k]);
			    for (; k < 16; ++k)
				printf("   ");
			    printf("  ");
			    for (k = 0; k < nl; ++k) {
				c = p[k];
				putchar((' ' <= c && c <= '~')? c: '.');
			    }
			    printf("\n");
			    q = "    ";
			    p += nl;
			    nb -= nl;
			} while (nb > 0);
			if (fcs != PPP_GOODFCS)
			    printf("     BAD FCS: (residue = %x)\n", fcs);
		    }
		    break;
		case '}':
		    if (!pkt->esc) {
			pkt->esc = 1;
			break;
		    }
		    /* else fall through */
		default:
		    if (pkt->esc) {
			c ^= 0x20;
			pkt->esc = 0;
		    }
		    pkt->buf[pkt->cnt++] = c;
		    break;
		}
	    }
	    break;
	case 3:
	case 4:
	    if (reverse)
		c = 7 - c;
	    dir = c==3? "send": "recv";
	    pkt = c==3? &spkt: &rpkt;
	    printf("end %s", dir);
	    if (pkt->cnt > 0)
		printf("  [%d bytes in incomplete packet]", pkt->cnt);
	    printf("\n");
	    break;
	case 5:
	case 6:
	case 7:
	    show_time(f, c);
	    break;
	default:
	    printf("?%.2x\n", c);
	}
    }
}
void PppCreateMessageFrameIp(void)
{
	U_INT msgLen, frameLen;
	U_SHORT fcs = PPP_INITFCS;
	U_CHAR *msgPtr = PppControl.OutMessageContainer.Buf;
	U_CHAR *framePtr = PppControl.OutFrameContainer.Buf;

	PPP_LOG_ENTRY(MDB_PppCreateMessageFrame);
	PPP_LOG_1(PppControl.OutMessageContainer.Length);

	PUTCHAR(PPP_FLAG, framePtr);
	frameLen = 1;

	for (msgLen = PppControl.OutMessageContainer.Length; msgLen > 0; msgLen--) {
		if ((*msgPtr == PPP_FLAG) || (*msgPtr == PPP_ESCAPE)) {
			frameLen++;
			PUTCHAR(PPP_ESCAPE, framePtr);
			PUTCHAR((*msgPtr) ^ PPP_TRANS, framePtr);
		} else {
			PUTCHAR(*msgPtr, framePtr);
		}
		PPP_FCS(fcs, *msgPtr);
		msgPtr++;
		frameLen++;
	}

	// Append FCS to Out Message, and update its length
	PPP_LOG_1(fcs);
	fcs ^= 0xffff;
	PPP_LOG_1(fcs);
	PUTCHAR_NOINC(fcs & 0xFF, msgPtr);
	PPP_LOG_1(*msgPtr);
	PUTCHAR_NOINC((fcs >> 8) & 0xFF, (msgPtr + 1));
	PPP_LOG_1(*(msgPtr + 1));
	PppControl.OutMessageContainer.Length += 2;

	// Add FCS to PPP encoded frame
	for (msgLen = 2; msgLen > 0; msgLen--) {
		if ((*msgPtr == PPP_FLAG) || (*msgPtr == PPP_ESCAPE)) {
			frameLen++;
			PUTCHAR(PPP_ESCAPE, framePtr);
			PUTCHAR((*msgPtr) ^ PPP_TRANS, framePtr);
		} else {
			PUTCHAR(*msgPtr, framePtr);
		}
		msgPtr++;
		frameLen++;

	}
	PUTCHAR(PPP_FLAG, framePtr);
	frameLen++;

	PPP_LOG_1(frameLen);

	PPP_TRACE_BUF("CreateMessageFrame: ", PppControl.OutFrameContainer.Buf, frameLen);

	PppControl.OutFrameContainer.Length = frameLen;

	PPP_LOG_EXIT();

}
void PppMessageReq(const U_CHAR *buf, U_INT length)
{
	MessageBufS *newMessage = NULL;
	BOOL isEnd = FALSE;
	U_CHAR *s, *d;		//s = running on source buffer, received from PC  d = runs on destination buffer
	QueueMessageS qMsg;
	PPP_LOG_ENTRY(MDB_PppMessageReq);
	PPP_LOG_1(length);

	PPP_TRACE_BUF("PppMessageReq: ", (U_CHAR *)buf, length);

	s = (U_CHAR *) buf;

	do {
		PPP_LOG_1(length);
		if (PppControl.IsRxFragmented) {
			PPP_LOG();
			newMessage = PppControl.InFramePlaceholder;

			if (newMessage == NULL) {
				PppControl.IsRxFragmented = FALSE;
				PppControl.IsEscapeFound = FALSE;
				PppControl.IncomingFcs = PPP_INITFCS;

				PppControl.APOOMDrops++;
				PPP_PRINTF("[PPP] %s: Fragmented Flag Error - Dropped %d AP packets\n",
					   __func__, (int)PppControl.APOOMDrops);
				PPP_LOG_EXIT();
				return;
			}

			d = &newMessage->Buf[newMessage->Length];
		} else {
			PPP_LOG();
			newMessage = PppAllocateMessage(PPP_FRAME_SIZE);
			PppControl.IsRxFragmented = FALSE;
			PppControl.IsEscapeFound = FALSE;
			PppControl.IncomingFcs = PPP_INITFCS;
			if (newMessage == NULL) {
				PppControl.APOOMDrops++;
				PPP_PRINTF("[PPP] %s: Dropped %d AP packets\n", __func__, (int)PppControl.APOOMDrops);
				PPP_LOG_EXIT();
				return;
			}

			d = newMessage->Buf;
		}

		while ((length > 0) && (!isEnd)) {
			if (*s == PPP_FLAG) {
				switch (PppControl.FlagState) {
				case HDLC_FLAG_NONE:
					PppControl.FlagState = HDLC_FLAG_FIRST;
					PPP_LOG();
					break;

				case HDLC_FLAG_FIRST:
					PPP_LOG();
					if (newMessage->Length != 0) {
						PppControl.FlagState = HDLC_FLAG_LAST;
						isEnd = TRUE;
						PPP_LOG();
					}
					break;
				default:
					break;
				}
			} else if (*s == PPP_ESCAPE) {
				PppControl.IsEscapeFound = TRUE;
			} else if (PppControl.IsEscapeFound) {
				PppControl.IsEscapeFound = FALSE;

				if (newMessage->Length < PppControl.lcpRecvParams.Mru.Mru + 3)	//protocol+FCS is also copied to buffer so add 3 bytes to MRU limit
				{
					PPP_ESCAPE_C(*d, *s);
					PPP_FCS(PppControl.IncomingFcs, *d);
					d++;
					newMessage->Length++;
				} else {
					newMessage->Length = 0xFFFF;
					break;
				}
			} else {
				if (newMessage->Length < PppControl.lcpRecvParams.Mru.Mru + 3)	//protocol+FCS is also copied to buffer so add 3 bytes to MRU limit
				{
					*d = *s;
					PPP_FCS(PppControl.IncomingFcs, *d);
					d++;
					newMessage->Length++;
				} else {
					newMessage->Length = 0xFFFF;
					break;
				}
			}
			s++;
			length--;
		}

		PPP_LOG_1(newMessage->Length);
		PPP_LOG_1(PppControl.lcpRecvParams.Mru.Mru);

		if (newMessage->Length > PppControl.lcpRecvParams.Mru.Mru + 3) {
			//Message too long - drop it, free memory and report
			PPP_PRINTF("[PPP] %s: Message too long, dropping...length=%d mru=%d\n", __func__, (int)newMessage->Length,
			       (int)PppControl.lcpRecvParams.Mru.Mru);
			PppFreeMessage(newMessage);
			newMessage = NULL;
			pppResetRecvState(&PppControl);
			isEnd = FALSE;
			while (length > 0 && *s != PPP_FLAG) {
				s++;
				length--;
			}
		}

		else if (!isEnd) {
			PPP_LOG_1(PppControl.FlagState);
			if (PppControl.FlagState == HDLC_FLAG_FIRST) {
				PPP_TRACE("IsFrarmented = TRUE");

				PppControl.IsRxFragmented = TRUE;

				PppControl.InFramePlaceholder = newMessage;

				newMessage = NULL;
			}
		} else {
			PPP_LOG_1(PppControl.IncomingFcs);

			if (PPP_GOODFCS == PppControl.IncomingFcs) {
				// Message is OK. newMessage.Length includes FCS, so decrease it by 2
				newMessage->Length -= 2;
				PPP_LOG_3((U_INT) newMessage, (U_INT) newMessage->Buf, newMessage->Length);
				PPP_TRACE_BUF("In-Decoded: ", newMessage->Buf, newMessage->Length);

				if (pppIsWriteThrough(newMessage) == TRUE) {
					if (PppControl.PppState == PPP_STATE_CONNECTED) {
						pppRelayMessageToCommDirect(newMessage);
					}
					PppFreeMessage(newMessage);
					newMessage = NULL;
				} else {
					qMsg.Type = PPP_MSG_REQ;
					qMsg.Ptr = (U_CHAR *)newMessage;
					PPP_LOG_1((U_INT)qMsg.Ptr);
					PPP_SEND_Q_MSG(PppControl.MsgQRef, &qMsg, sizeof(qMsg));
					newMessage = NULL;
				}
			} else {
				PppFreeMessage(newMessage);
				newMessage = NULL;
				PPP_PRINTF("[PPP] %s: Wrong checksum, dropping message:%x\n", __func__, PppControl.IncomingFcs);
			}

			pppResetRecvState(&PppControl);
			isEnd = FALSE;
		}

	} while (length > 0);

	if (newMessage != NULL) {
		PppFreeMessage(newMessage);
	}

	PPP_LOG_EXIT();
}