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

📄 cppp.cpp

📁 PPP协议的实现演示
💻 CPP
字号:
#include "globals.h"/***************************************************************************                          cppp.cpp  -  description                             -------------------    begin                : Wed Jul 25 2001    copyright            : (C) 2001 by stephane (birdy57)    email                : birdy57@pengaol.org ***************************************************************************//* original code from :* Copyright (c) 1989 Carnegie Mellon University.* All rights reserved. *//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "cppp.h"#ifdef WITH_PPPCPpp::CPpp(){    m_sDevice = new char[30];    m_cParam = new CParamConfig[3];    m_cParam[0].DriverClass = "CPppDriver";    m_cParam[0].Msg = "Vers 0.55 Linux";    m_cParam[0].Author = "Birdy57";    m_cParam[0].Guid = 0x3812;	//xxyz y=systeme z=2 drivers out    m_cParam[1].Request = "*Device";    m_cParam[1].Default = "ppp0";    m_cParam[1].InitStr = m_sDevice;    m_cParam[1].MaxBufferLen = 30;    m_cParam[2].Request = NULL;    m_cParam[2].Default = NULL;    m_cParam[2].MaxBufferLen = 0;    m_bIsConnected = false;//static struct utsname utsname;        /* for the kernel version *///static int kernel_version;    PppTools = new CPppTools;    bFirstFrame = true;// variables global    looped = 0;    demand = 1;    req_unit = 0;    new_style_driver = 1;    slave_fd = -1;    ppp_disc = N_PPP;		/* The PPP discpline */    sync_serial = 1;		/* Device is synchronous serial device */    multilink = 0;    kdebugflag = 0;    driver_version = 0;    driver_modification = 0;    driver_patch = 0;    driver_is_old = 0;    tty_disc = N_TTY;		/* The TTY discipline */    if_is_up = 0;}CPpp::~CPpp(){    delete m_sDevice;    delete[]m_cParam;}/** add_fd - add an fd to the set that wait_input waits for. */void CPpp::add_fd(int fd){    FD_SET(fd, &in_fds);    if (fd > max_in_fd)	max_in_fd = fd;}/** set_kdebugflag - Define the debugging level for the kernel */int CPpp::set_kdebugflag(int requested_level){    if (new_style_driver && ifunit < 0)	return 1;    if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {	if (!ok_error(errno))	    printf("ioctl(PPPIOCSDEBUG): \n");	return (0);    }    return (1);}/** creer une interface ppp */int CPpp::make_ppp_unit(){    int x;    ifunit = req_unit;    x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);    if (x < 0 && req_unit >= 0 && errno == EEXIST) {	ErrorNbr = 163;	ifunit = -1;	x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);    }    if (x < 0)	ErrorNbr = 164;    return x;}/** fournit les flags */int CPpp::get_flags(int fd){    int flags;    if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) & flags) < 0) {	if (ok_error(errno))	    flags = 0;    }    return flags;}/** applique les flags */void CPpp::set_flags(int fd, int flags){    if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) & flags) < 0) {	if (!ok_error(errno))	    ErrorNbr = 165;    }}/** attache un periph */int CPpp::bundle_attach(int ifnum){    if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) {	if (errno == ENXIO)	    return 0;		/* doesn't still exist */	printf("Couldn't attach to interface unit %d: \n", ifnum);    }    if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)	printf("Couldn't connect to interface unit %d: \n", ifnum);    set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK);    ifunit = ifnum;    return 1;}/** applique le fd */void CPpp::set_ppp_fd(int new_fd){    ppp_fd = new_fd;}/** initalise le systeme */bool CPpp::sys_init(void){    bool bRet = false;    int flags;    ppp_dev_fd = open("/dev/ppp", O_RDWR);    if (ppp_dev_fd < 0)	ErrorNbr = 160;    else {	flags = fcntl(ppp_dev_fd, F_GETFL);	if (flags == -1 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)	// flags | O_NONBLOCK	    ErrorNbr = 161;	else {	    FD_ZERO(&in_fds);	    max_in_fd = 0;	    bRet = true;	}    }    return bRet;}/** tty_establish_ppp - Turn the serial port into a ppp interface. */int CPpp::tty_establish_ppp(int tty_fd){    int x;    int fd = -1;/* * Ensure that the tty device is in exclusive mode. */    if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {	if (!ok_error(errno))	    return -1;    }/* * Demand mode - prime the old ppp device to relinquish the unit. */    if (!new_style_driver && looped	&& ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {	ErrorNbr = 166;	return -1;    }/* * Set the current tty to the PPP discpline */#ifndef N_SYNC_PPP#define N_SYNC_PPP 14#endif    ppp_disc = (new_style_driver && sync_serial) ? N_SYNC_PPP : N_PPP;    if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {	if (!ok_error(errno)) {	    ErrorNbr = 167;	    return -1;	}    }    if (new_style_driver) {	/* Open another instance of /dev/ppp and connect the channel to it */	int flags;	if (ioctl(tty_fd, PPPIOCGCHAN, &chindex) == -1) {	    ErrorNbr = 168;	    goto err;	}	fd = open("/dev/ppp", O_RDWR);	if (fd < 0) {	    ErrorNbr = 169;	    goto err;	}	if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {	    ErrorNbr = 170;	    goto err_close;	}	flags = fcntl(fd, F_GETFL);	if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)	// O_NONBLOCK	    ErrorNbr = 171;	set_ppp_fd(fd);	if (!looped)	    ifunit = -1;	if (!looped && !multilink) {	    /*	     * Create a new PPP unit.	     */	    if (make_ppp_unit() < 0)		goto err_close;	}	if (looped)	    set_flags(ppp_dev_fd,		      get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC);	if (!multilink) {	    add_fd(ppp_dev_fd);	    if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {		ErrorNbr = 172;		goto err_close;	    }	}    } else {	/*	 * Old-style driver: find out which interface we were given.	 */	set_ppp_fd(tty_fd);	if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) {	    if (ok_error(errno))		goto err;	    ErrorNbr = 173;	}	ifunit = x;	/*	 * Fetch the initial file flags and reset blocking mode on the file.	 */	initfdflags = fcntl(tty_fd, F_GETFL);	if (initfdflags == -1 ||	    fcntl(tty_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {	    if (!ok_error(errno))		ErrorNbr = 171;	}    }    looped = 0;    /*     * Enable debug in the driver if requested.     */    if (!looped)	set_kdebugflag(kdebugflag);#define SC_RCVB	(SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)#define SC_LOGB	(SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \		 | SC_LOG_FLUSH)    set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB))		       | ((kdebugflag * SC_DEBUG) & SC_LOGB)));    return ppp_fd;  err_close:    close(fd);  err:    ioctl(tty_fd, TIOCSETD, &tty_disc);	// < 0 && !ok_error(errno);    return -1;}/** Allocate pseudo tty, returns master side fd.  */int CPpp::pty_open(char *sl_name){    char ptyname[] = "/dev/ptyXY";    char ch[] = "pqrstuvwxyz";    char digit[] = "0123456789abcdefghijklmnopqrstuv";    int l, m;    int mr_fd;    /* This algorithm should work for almost all standard Unices */    for (l = 0; ch[l]; l++) {	for (m = 0; digit[m]; m++) {	    ptyname[8] = ch[l];	    ptyname[9] = digit[m];	    /* Open the master */	    if ((mr_fd = open(ptyname, O_RDWR)) < 0)		continue;	    /* Check the slave */	    ptyname[5] = 't';	    if ((access(ptyname, R_OK | W_OK)) < 0) {		close(mr_fd);		ptyname[5] = 'p';		continue;	    }	    strcpy(sl_name, ptyname);	    return mr_fd;	}    }    return -1;}/** test si ppp est possible */bool CPpp::IsAvailable(){    bool bRet = false;    ppp_dev_fd = open("/dev/ppp", O_RDWR);    if (ppp_dev_fd > 0) {	close(ppp_dev_fd);	if (Connect()) {	    bRet = true;	    Disconnect();	}    }    return bRet;}/** connection au periph */bool CPpp::Connect(){    bool bRet = false;    char ttyname[32];    int osmaj, osmin, ospatch;    unsigned int max = 255;    if (!m_bIsConnected) {	if ((nFd_master = pty_open(ttyname)) != -1) {	    /* trouve la version du kernel */	    uname(&utsname);	    osmaj = osmin = ospatch = 0;	    sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);	    kernel_version = KVERSION(osmaj, osmin, ospatch);	    if (sys_init()) {		bRet = true;		nFd_ppp = open(ttyname, O_RDWR);		//set_up_tty(nFd_ppp,0,1);		if ((nFd_ipp = tty_establish_ppp(nFd_ppp)) != -1) {		    ioctl(nFd_ipp, PPPIOCSMAXCID, (caddr_t) & max);		    set_flags(nFd_ipp, SC_COMP_TCP | SC_NO_TCP_CCID);		    sprintf(ifname, "%s%d", PPP_DRV_NAME, ifunit);		    sprintf(m_sDevice, "%s%d", PPP_DRV_NAME, ifunit);		    //sifvjcomp (nFd_ipp, 1,0,255);		    bRet = true;		    m_bIsConnected = true;		}	    }	}    }    return bRet;}/** arrete l'interface */bool CPpp::Disconnect(){    bool bRet = false;    if (m_bIsConnected) {	tty_disestablish_ppp(nFd_ppp);	//ioctl(ppp_dev_fd, PPPIOCDETACH);	close(nFd_ipp);	close(nFd_ppp);	close(nFd_master);	m_bIsConnected = false;	bRet = true;    }    return bRet;}/** fournit les requetes */CParamConfig *CPpp::GetRequest(){    return m_cParam;}// int CPpp::Read(char *pData, int nSize){    int nLong = 0;    int nlimit;    char sTmp[3000];    int ppphdr = 4;    int nread;  boucle:    nLong = 0;    // Lit l'ent阾e pour connaitre la longueur de la trame    nread = 0;    while (nread < 10)	nread += read(nFd_master, sTmp, 10);    memcpy(pData, &sTmp[ppphdr], 10 - ppphdr);    nLong = ntohs(*((short *) &pData[2]));    // vide le buffer si la longueur semble incorrecte    if (nLong > 1600) {	read(nFd_master, sTmp, 3000);	goto boucle;    }    // Maintenant lit la trame dans son entier    while (nread < nLong + ppphdr)	nread +=	    read(nFd_master, &pData[nread - ppphdr],		 nLong - nread + ppphdr);    return nLong;}/** ecriture sur le periph */int CPpp::Write(char *pData, int nSize){    int nLong = 0;    unsigned char sTmp[2000];    sTmp[0] = 0x7e;    sTmp[1] = 0xff;    sTmp[2] = 0x03;    sTmp[3] = 0x00;    sTmp[4] = 0x21;    memcpy(&sTmp[5], pData, nSize);    nLong = nSize;    nLong += 8;    sTmp[nLong - 1] = 0x7e;    PppTools->Recompute_pppfchks((unsigned char *) &sTmp[1], nLong - 2);    if (bFirstFrame) {	nSize = write(nFd_master, &sTmp[1], nLong - 1);    } else {	nSize = write(nFd_master, &sTmp[1], nLong - 3);    }    bFirstFrame = false;    return nSize;}/** definie si connecte ou pas */bool CPpp::IsConnected(){    return m_bIsConnected;}/*********************************************************************  sifvjcomp - config tcp header compression */int CPpp::sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid){    u_int x = get_flags(ppp_dev_fd);    if (vjcomp) {	if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) & maxcid) < 0)	    vjcomp = 0;    }    x = vjcomp ? x | SC_COMP_TCP : x & ~SC_COMP_TCP;    x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;    set_flags(ppp_dev_fd, x);    return 1;}/** setuptty */void CPpp::set_up_tty(int tty_fd, int local, int crtscts){    int speed;    struct termios tios;    tcgetattr(tty_fd, &tios);    tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);    tios.c_cflag |= CS8 | CREAD | HUPCL;    tios.c_iflag = IGNBRK | IGNPAR;    tios.c_oflag = 0;    tios.c_lflag = 0;    tios.c_cc[VMIN] = 1;    tios.c_cc[VTIME] = 0;    if (local)	tios.c_cflag ^= (CLOCAL | HUPCL);    switch (crtscts) {    case 1:	tios.c_cflag |= CRTSCTS;	break;    case -2:	tios.c_iflag |= IXON | IXOFF;	tios.c_cc[VSTOP] = 0x13;	/* DC3 = XOFF = ^S */	tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */	break;    case -1:	tios.c_cflag &= ~CRTSCTS;	break;    default:	break;    }    cfsetospeed(&tios, speed);    cfsetispeed(&tios, speed);    tcsetattr(tty_fd, TCSAFLUSH, &tios);}/** lit 1 octet */unsigned char CPpp::Mread(){    unsigned char c;    while (read(nFd_master, &c, 1) < 0);    return c;}/** detache ppp */void CPpp::tty_disestablish_ppp(int tty_fd){    /*     * Flush the tty output buffer so that the TIOCSETD doesn't hang.     */    tcflush(tty_fd, TCIOFLUSH);/* * Restore the previous line discipline */    ioctl(tty_fd, TIOCSETD, &tty_disc);    ioctl(tty_fd, TIOCNXCL, 0);    /* Reset non-blocking mode on fd. */    fcntl(tty_fd, F_SETFL, initfdflags);    initfdflags = -1;    if (new_style_driver) {	close(ppp_fd);	ppp_fd = -1;	ioctl(ppp_dev_fd, PPPIOCDETACH);	//if (!multilink)	//    remove_fd(ppp_dev_fd);	FD_CLR(ppp_dev_fd, &in_fds);    }}#endif

⌨️ 快捷键说明

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