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

📄 if_ppp.c

📁 经典的ppp程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * if_ppp.c - a network interface connected to a STREAMS module. * * Copyright (c) 1994 The Australian National University. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, provided that the above copyright * notice appears in all copies.  This software is provided without any * warranty, express or implied. The Australian National University * makes no representations about the suitability of this software for * any purpose. * * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * * $Id: if_ppp.c,v 1.17 1999/12/23 01:48:45 paulus Exp $ *//* * This file is used under SunOS 4 and Digital UNIX. * * This file provides the glue between PPP and IP. */#define INET	1#include <sys/types.h>#include <sys/param.h>#include <sys/errno.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <net/if.h>#include <net/netisr.h>#include <net/ppp_defs.h>#include <net/pppio.h>#include <netinet/in.h>#include <netinet/in_var.h>#ifdef __osf__#include <sys/ioctl.h>#include <net/if_types.h>#else#include <sys/sockio.h>#endif#include "ppp_mod.h"#include <sys/stream.h>#ifdef SNIT_SUPPORT#include <sys/time.h>#include <net/nit_if.h>#include <netinet/if_ether.h>#endif#ifdef __osf__#define SIOCSIFMTU SIOCSIPMTU#define SIOCGIFMTU SIOCRIPMTU#define IFA_ADDR(ifa)   (*(ifa)->ifa_addr)#else#define IFA_ADDR(ifa)   ((ifa)->ifa_addr)#endif#define ifr_mtu		ifr_metricstatic int if_ppp_open __P((queue_t *, int, int, int));static int if_ppp_close __P((queue_t *, int));static int if_ppp_wput __P((queue_t *, mblk_t *));static int if_ppp_rput __P((queue_t *, mblk_t *));#define PPP_IF_ID 0x8021static struct module_info minfo = {    PPP_IF_ID, "if_ppp", 0, INFPSZ, 4096, 128};static struct qinit rinit = {    if_ppp_rput, NULL, if_ppp_open, if_ppp_close, NULL, &minfo, NULL};static struct qinit winit = {    if_ppp_wput, NULL, NULL, NULL, NULL, &minfo, NULL};struct streamtab if_pppinfo = {    &rinit, &winit, NULL, NULL};typedef struct if_ppp_state {    int unit;    queue_t *q;    int flags;} if_ppp_t;/* Values for flags */#define DBGLOG		1static int if_ppp_count;	/* Number of currently-active streams */static int ppp_nalloc;		/* Number of elements of ifs and states */static struct ifnet **ifs;	/* Array of pointers to interface structs */static if_ppp_t **states;	/* Array of pointers to state structs */static int if_ppp_output __P((struct ifnet *, struct mbuf *,			      struct sockaddr *));static int if_ppp_ioctl __P((struct ifnet *, u_int, caddr_t));static struct mbuf *make_mbufs __P((mblk_t *, int));static mblk_t *make_message __P((struct mbuf *, int));#ifdef SNIT_SUPPORT/* Fake ether header for SNIT */static struct ether_header snit_ehdr = {{0}, {0}, ETHERTYPE_IP};#endif#ifndef __osf__static void ppp_if_detach __P((struct ifnet *));/* * Detach all the interfaces before unloading. * Not sure this works. */intif_ppp_unload(){    int i;    if (if_ppp_count > 0)	return EBUSY;    for (i = 0; i < ppp_nalloc; ++i)	if (ifs[i] != 0)	    ppp_if_detach(ifs[i]);    if (ifs) {	FREE(ifs, ppp_nalloc * sizeof (struct ifnet *));	FREE(states, ppp_nalloc * sizeof (struct if_ppp_t *));    }    ppp_nalloc = 0;    return 0;}#endif /* __osf__ *//* * STREAMS module entry points. */static intif_ppp_open(q, dev, flag, sflag)    queue_t *q;    int dev;    int flag, sflag;{    if_ppp_t *sp;    if (q->q_ptr == 0) {	sp = (if_ppp_t *) ALLOC_SLEEP(sizeof (if_ppp_t));	if (sp == 0)	    return OPENFAIL;	bzero(sp, sizeof (if_ppp_t));	q->q_ptr = (caddr_t) sp;	WR(q)->q_ptr = (caddr_t) sp;	sp->unit = -1;		/* no interface unit attached at present */	sp->q = WR(q);	sp->flags = 0;	++if_ppp_count;    }    return 0;}static intif_ppp_close(q, flag)    queue_t *q;    int flag;{    if_ppp_t *sp;    struct ifnet *ifp;    sp = (if_ppp_t *) q->q_ptr;    if (sp != 0) {	if (sp->flags & DBGLOG)	    printf("if_ppp closed, q=%x sp=%x\n", q, sp);	if (sp->unit >= 0) {	    if (sp->unit < ppp_nalloc) {		states[sp->unit] = 0;		ifp = ifs[sp->unit];		if (ifp != 0)		    ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);#ifdef DEBUG	    } else {		printf("if_ppp: unit %d nonexistent!\n", sp->unit);#endif	    }	}	FREE(sp, sizeof (if_ppp_t));	--if_ppp_count;    }    return 0;}static intif_ppp_wput(q, mp)    queue_t *q;    mblk_t *mp;{    if_ppp_t *sp;    struct iocblk *iop;    int error, unit;    struct ifnet *ifp;    sp = (if_ppp_t *) q->q_ptr;    switch (mp->b_datap->db_type) {    case M_DATA:	/*	 * Now why would we be getting data coming in here??	 */	if (sp->flags & DBGLOG)	    printf("if_ppp: got M_DATA len=%d\n", msgdsize(mp));	freemsg(mp);	break;    case M_IOCTL:	iop = (struct iocblk *) mp->b_rptr;	error = EINVAL;	if (sp->flags & DBGLOG)	    printf("if_ppp: got ioctl cmd=%x count=%d\n",		   iop->ioc_cmd, iop->ioc_count);	switch (iop->ioc_cmd) {	case PPPIO_NEWPPA:		/* well almost */	    if (iop->ioc_count != sizeof(int) || sp->unit >= 0)		break;	    if ((error = NOTSUSER()) != 0)		break;	    unit = *(int *)mp->b_cont->b_rptr;	    /* Check that this unit isn't already in use */	    if (unit < ppp_nalloc && states[unit] != 0) {		error = EADDRINUSE;		break;	    }	    /* Extend ifs and states arrays if necessary. */	    error = ENOSR;	    if (unit >= ppp_nalloc) {		int newn;		struct ifnet **newifs;		if_ppp_t **newstates;		newn = unit + 4;		if (sp->flags & DBGLOG)		    printf("if_ppp: extending ifs to %d\n", newn);		newifs = (struct ifnet **)		    ALLOC_NOSLEEP(newn * sizeof (struct ifnet *));		if (newifs == 0)		    break;		bzero(newifs, newn * sizeof (struct ifnet *));		newstates = (if_ppp_t **)		    ALLOC_NOSLEEP(newn * sizeof (struct if_ppp_t *));		if (newstates == 0) {		    FREE(newifs, newn * sizeof (struct ifnet *));		    break;		}		bzero(newstates, newn * sizeof (struct if_ppp_t *));		bcopy(ifs, newifs, ppp_nalloc * sizeof(struct ifnet *));		bcopy(states, newstates, ppp_nalloc * sizeof(if_ppp_t *));		if (ifs) {		    FREE(ifs, ppp_nalloc * sizeof(struct ifnet *));		    FREE(states, ppp_nalloc * sizeof(if_ppp_t *));		}		ifs = newifs;		states = newstates;		ppp_nalloc = newn;	    }	    /* Allocate a new ifnet struct if necessary. */	    ifp = ifs[unit];	    if (ifp == 0) {		ifp = (struct ifnet *) ALLOC_NOSLEEP(sizeof (struct ifnet));		if (ifp == 0)		    break;		bzero(ifp, sizeof (struct ifnet));		ifs[unit] = ifp;		ifp->if_name = "ppp";		ifp->if_unit = unit;		ifp->if_mtu = PPP_MTU;		ifp->if_flags = IFF_POINTOPOINT | IFF_RUNNING;#ifndef __osf__#ifdef IFF_MULTICAST		ifp->if_flags |= IFF_MULTICAST;#endif#endif /* __osf__ */		ifp->if_output = if_ppp_output;#ifdef __osf__		ifp->if_version = "Point-to-Point Protocol, version 2.3.11";		ifp->if_mediamtu = PPP_MTU;		ifp->if_type = IFT_PPP;		ifp->if_hdrlen = PPP_HDRLEN;		ifp->if_addrlen = 0;		ifp->if_flags |= IFF_NOARP | IFF_SIMPLEX | IFF_NOTRAILERS;#ifdef IFF_VAR_MTU		ifp->if_flags |= IFF_VAR_MTU;#endif#ifdef NETMASTERCPU		ifp->if_affinity = NETMASTERCPU;#endif#endif		ifp->if_ioctl = if_ppp_ioctl;		ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;		if_attach(ifp);		if (sp->flags & DBGLOG)		    printf("if_ppp: created unit %d\n", unit);	    } else {		ifp->if_mtu = PPP_MTU;		ifp->if_flags |= IFF_RUNNING;	    }	    states[unit] = sp;	    sp->unit = unit;	    error = 0;	    iop->ioc_count = 0;	    if (sp->flags & DBGLOG)		printf("if_ppp: attached unit %d, sp=%x q=%x\n", unit,		       sp, sp->q);	    break;	case PPPIO_DEBUG:	    error = -1;	    if (iop->ioc_count == sizeof(int)) {		if (*(int *)mp->b_cont->b_rptr == PPPDBG_LOG + PPPDBG_IF) {		    printf("if_ppp: debug log enabled, q=%x sp=%x\n", q, sp);		    sp->flags |= DBGLOG;		    error = 0;		    iop->ioc_count = 0;		}	    }	    break;	default:	    error = -1;	    break;	}	if (sp->flags & DBGLOG)	    printf("if_ppp: ioctl result %d\n", error);	if (error < 0)	    putnext(q, mp);	else if (error == 0) {	    mp->b_datap->db_type = M_IOCACK;	    qreply(q, mp);	} else {	    mp->b_datap->db_type = M_IOCNAK;	    iop->ioc_count = 0;	    iop->ioc_error = error;	    qreply(q, mp);	}	break;    default:	putnext(q, mp);    }    return 0;}static intif_ppp_rput(q, mp)    queue_t *q;    mblk_t *mp;{    if_ppp_t *sp;    int proto, s;    struct mbuf *mb;    struct ifqueue *inq;    struct ifnet *ifp;    int len;    sp = (if_ppp_t *) q->q_ptr;    switch (mp->b_datap->db_type) {    case M_DATA:	/*	 * Convert the message into an mbuf chain	 * and inject it into the network code.	 */	if (sp->flags & DBGLOG)	    printf("if_ppp: rput pkt len %d data %x %x %x %x %x %x %x %x\n",		   msgdsize(mp), mp->b_rptr[0], mp->b_rptr[1], mp->b_rptr[2],		   mp->b_rptr[3], mp->b_rptr[4], mp->b_rptr[5], mp->b_rptr[6],		   mp->b_rptr[7]);	if (sp->unit < 0) {	    freemsg(mp);	    break;	}	if (sp->unit >= ppp_nalloc || (ifp = ifs[sp->unit]) == 0) {#ifdef DEBUG	    printf("if_ppp: no unit %d!\n", sp->unit);#endif	    freemsg(mp);	    break;	}	if ((ifp->if_flags & IFF_UP) == 0) {	    freemsg(mp);	    break;	}	++ifp->if_ipackets;	proto = PPP_PROTOCOL(mp->b_rptr);	adjmsg(mp, PPP_HDRLEN);	len = msgdsize(mp);	mb = make_mbufs(mp, sizeof(struct ifnet *));	freemsg(mp);	if (mb == NULL) {	    if (sp->flags & DBGLOG)		printf("if_ppp%d: make_mbufs failed\n", ifp->if_unit);	    ++ifp->if_ierrors;	    break;	}#ifdef SNIT_SUPPORT	if (proto == PPP_IP && (ifp->if_flags & IFF_PROMISC)) {	    struct nit_if nif;	    nif.nif_header = (caddr_t) &snit_ehdr;	    nif.nif_hdrlen = sizeof(snit_ehdr);	    nif.nif_bodylen = len;	    nif.nif_promisc = 0;

⌨️ 快捷键说明

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