⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lapb-test.c

📁 ppp协议实现源代码
💻 C
字号:
/* * Test routines for LAP-B driver. * * This code may be used for any purpose as long as the author's * copyright is cited in any source code distributed.  This code * is also available electronically from the author's web site. * * http://people.ne.mediaone.net/carlson/ppp * * http://www.workingcode.com/ppp * * Copyright 1999 by James Carlson and Working Code */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "sysdep.h"#include "util.h"#include "ahdlc.h"#include "lapb.h"/* State structure for LAP-B testing */struct session {    char *name;		/* Session name */    void *state;	/* Handle from LAP-B engine */    void *line;		/* Handle from AHDLC (if used) */    int seqnum;		/* Message number to send */    int doxmit;		/* State flag; LAP-B still has frames to send */    int sent;		/* Number of messages sent */    int received;	/* Number of messages received */    int loses;		/* Intentionally dropped data frames */    int tosend;		/* Number of messages to send during test */    int errors;		/* Mismatched messages received */};static struct session dte,dce;/* Global flag -- dump all data in hex. */static int showdata;/* * Handle downcall from LAP-B.  This would normally enable the hardware * transmit-empty interrupt and cause AHDLC to make a transmit upcall * into the LAP-B engine. */voidenable_transmit(void){#ifdef DEBUG_TEST    printf("LAP-B requests call to transmit routine.\n");#endif    dte.doxmit = dce.doxmit = 1;}/* * Handle LAP-B data reception.  Normally, this would go up to the * PPP state machines or do a "wakeup" on a process-level component. * Here, we just fetch the received frames, print them, and check * integrity. */static voidlapb_rcvd(void *state){    struct session *sp = (struct session *)state;    int len,snum;    octet *bufp,*bp;    if (showdata)	printf("LAP-B %s received data.\n",sp->name);    for (;;) {	len = lapb_receive(sp->state,&bufp);	if (bufp == NULL)	    break;	sp->received++;	/* Note:  no terminating NUL byte on message; atoi won't do. */	snum = 0;	for (bp = bufp+15; bp < bufp+len; bp++)	    snum = (snum*10) + (*bp - '0');	if ((bufp[12] ^ sp->name[1]) != ('t' ^ 'c') ||	    snum != sp->received+sp->loses) {	    printf("ERROR:  expected (d%ce,%d) but got (d%ce,%d)\n",		   sp->name[1]^'t'^'c',sp->received+sp->loses,		   bufp[12],snum);	    sp->errors++;	}	if (showdata)	    dump_buffer(bufp,len);	buffer_release(bufp);    }}/* * Handle LAP-B upcall.  In a real system, this would dequeue buffers * from a device structure and pass them down to LAP-B transmit.  Here * we just fabricate some test packets to send. */static voidlapb_hasroom(void *state){    struct session *sp = (struct session *)state;    octet *bp;    int retv;#ifdef DEBUG_TEST    printf("LAP-B %s has output room.\n",sp->name);#endif    for (;;) {	if (sp->tosend <= 0)	    break;	sp->seqnum++;#ifdef DEBUG_TEST	printf("%s insert message number %d\n",sp->name,sp->seqnum);#endif	sp->tosend--;	bp = (octet *)buffer_fetch(LAPB_OVERHEAD+20);	bp += LAPB_OVERHEAD;	sprintf(bp,"hello from %s %d",sp->name,sp->seqnum);	sp->sent++;	retv = lapb_send(sp->state,bp,strlen(bp));	if (retv)	    break;    }}void interrupts_off(void) {}void interrupts_on(void) {}void wakeup(void *event) {}void sleep(void *event, int level) {}intmain(argc,argv)int argc;char **argv;{    int i,len,useahdlc,dropone,supermode,timertest,queuemode,millisec;    octet *bufp,*bufp2;    char obuffer[32];    useahdlc = dropone = supermode = timertest = queuemode = 0;    while ((i=getopt(argc,argv,"adqrst")) != EOF)	switch (i) {	case 'a':	    useahdlc++;	    break;	case 'd':	    showdata++;	    break;	case 'q':	    queuemode++;	    break;	case 'r':	    dropone++;	    break;	case 's':	    supermode++;	    break;	case 't':	    timertest++;	    break;	case '?':	    fprintf(stderr,"Usage:\n\t%s [-adqrst] [dte-count [dce-count]]\n",		    argv[0]);	    exit(1);	}    if (optind < argc)	dte.tosend = atoi(argv[optind++]);    else	dte.tosend = 20;    if (optind < argc)	dce.tosend = atoi(argv[optind++]);    else	dce.tosend = 20;    if (optind < argc)	fprintf(stderr,"Extraneous command line arguments ignored.\n");    /* Create two LAP-B sessions and loop them together. */    if (supermode)	dte.state = lapb_create(MODE_SUPER,10,10,0,0,LBF_ISDTE);    else	dte.state = lapb_create(MODE_BASIC,7,7,0,0,LBF_ISDTE);    assert(dte.state != NULL);    printf("Allocated DTE state structure %p\n",dte.state);    if (supermode)	dce.state = lapb_create(MODE_SUPER,10,10,0,0,0);    else	dce.state = lapb_create(MODE_BASIC,7,7,0,0,0);    assert(dce.state != NULL);    printf("Allocated DCE state structure %p\n",dce.state);    dte.name = "dte";    dce.name = "dce";    dte.doxmit = dce.doxmit = 1;    if (useahdlc) {	dte.line = ahdlc_create();	ahdlc_handlers(dte.line,dte.state,lapb_input,lapb_transmit);	dce.line = ahdlc_create();	ahdlc_handlers(dce.line,dce.state,lapb_input,lapb_transmit);    }    /* Install received data handlers and initialize */    lapb_handlers(dte.state,&dte,lapb_rcvd,lapb_hasroom);    lapb_handlers(dce.state,&dce,lapb_rcvd,lapb_hasroom);    if (queuemode) {	lapb_hasroom((void *)&dte);	lapb_hasroom((void *)&dce);    } else {	lapb_control(dte.state,1);	lapb_control(dce.state,1);    }    /* Run tests */    for (i = 0; i < 20 ||	     (i < 1000 && (dte.doxmit || dce.doxmit)); i++) {	millisec = nextevent();#ifdef DEBUG_TEST	if (millisec >= 0)	    printf("%d milliseconds to next event.\n",millisec);#endif	if (timertest) {	    if (i == 15) {		printf("Firing off an event.\n");		timeelapsed(-1);	    } else		timeelapsed(500);	}	if (dte.doxmit != 0) {	    if (useahdlc) {		len = ahdlc_transmit(dte.line,obuffer,sizeof(obuffer));		if (len > 0) {		    if (showdata) {			printf("Looping back %d characters from DTE to DCE\n",			       len);			dump_buffer(obuffer,len);		    }		    ahdlc_receive(dce.line,obuffer,len);		} else {		    if (showdata)			printf("LAP-B DTE out of data to send.\n");		    dte.doxmit = 0;		}	    } else {		/*		 * Get next frame that the DTE side LAP-B is sending.  In a		 * normal system, this would be done by an AHDLC upcall.		 */		lapb_transmit(dte.state,&bufp,&len);		if (bufp != NULL) {		    if (showdata) {			printf("LAP-B DTE sent frame.\n");			dump_buffer(bufp,len);		    }		    if ((dropone && i == 6) ||			(timertest && i >= 15 && i < 17)) {			printf(		"Intentionally dropping this one (will cause%s loss).\n",			       queuemode?"":" no");			if (queuemode)			    dce.loses++;		    } else {			/*			 * Note:  transmitter must not free buffer, but			 * receiver does free it.  Therefore, for this			 * test code we have to do a data copy.  This will			 * not happen in real life.			 */			bufp2 = (octet *)buffer_fetch(len);			memcpy(bufp2,bufp,len);			/* Send this into the other guy's input */			lapb_input(dce.state,bufp2,len);		    }		} else {		    if (showdata)			printf("LAP-B DTE out of data to send.\n");		    dte.doxmit = 0;		}	    }	}	if (dce.doxmit != 0) {	    if (useahdlc) {		len = ahdlc_transmit(dce.line,obuffer,sizeof(obuffer));		if (len > 0) {		    if (showdata) {			printf("Looping back %d characters from DCE to DTE\n",			       len);			dump_buffer(obuffer,len);		    }		    ahdlc_receive(dte.line,obuffer,len);		} else {		    if (showdata)			printf("LAP-B DCE out of data to send.\n");		    dce.doxmit = 0;		}	    } else {		/* Get the next frame from the LAP-B DCE side */		lapb_transmit(dce.state,&bufp,&len);		if (bufp != NULL) {		    if (showdata) {			printf("LAP-B DCE sent frame.\n");			dump_buffer(bufp,len);		    }		    bufp2 = (octet *)buffer_fetch(len);		    memcpy(bufp2,bufp,len);		    /* Send this into the other guy's input */		    lapb_input(dte.state,bufp2,len);		} else {		    if (showdata)			printf("LAP-B DCE out of data to send.\n");		    dce.doxmit = 0;		}	    }	}    }    /* Clean up. */    ahdlc_destroy(dte.line);    ahdlc_destroy(dce.line);    /* Display the results. */    printf("DTE:  %d sent, %d received, %d remain.\n",dte.sent,dte.received,	   dte.tosend);    printf("DCE:  %d sent, %d received, %d remain.\n",dce.sent,dce.received,	   dce.tosend);    buffer_status();    if (dte.tosend != 0 || dce.tosend != 0 || dte.errors != 0 ||	dce.errors != 0 || dte.sent != dce.received+dce.loses ||	dce.sent != dte.received)	printf("ERROR:  Some data lost.\n");    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -