/*
* if_ppp.c - a network interface connected to a STREAMS module.
*
- * Copyright (c) 1994 The Australian National University.
- * All rights reserved.
+ * Copyright (c) 1994 Paul Mackerras. 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.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
*
- * $Id: if_ppp.c,v 1.2 1996/08/28 06:35:11 paulus Exp $
+ * 3. The name(s) of the authors of this software must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * 4. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by Paul Mackerras
+ * <paulus@samba.org>".
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Id: if_ppp.c,v 1.18 2002/12/06 09:49:15 paulus Exp $
*/
/*
#include <sys/types.h>
#include <sys/param.h>
-#include <sys/stream.h>
#include <sys/errno.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#ifdef __osf__
#include <sys/ioctl.h>
#include <net/if_types.h>
-#include "ppp_mod.h"
#else
#include <sys/sockio.h>
-#include <modules/ppp_mod.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 ifr_mtu ifr_metric
-#define PPP_MINMTU 64
-#define PPP_MAXMTU 65536
-
static 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 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 *));
for (i = 0; i < ppp_nalloc; ++i)
if (ifs[i] != 0)
ppp_if_detach(ifs[i]);
- FREE(ifs, ppp_nalloc * sizeof (struct ifnet *));
- FREE(states, ppp_nalloc * sizeof (struct if_ppp_t *));
+ if (ifs) {
+ FREE(ifs, ppp_nalloc * sizeof (struct ifnet *));
+ FREE(states, ppp_nalloc * sizeof (struct if_ppp_t *));
+ }
ppp_nalloc = 0;
return 0;
}
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 *));
- FREE(ifs, ppp_nalloc * sizeof(struct ifnet *));
- FREE(states, 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;
ifs[unit] = ifp;
ifp->if_name = "ppp";
ifp->if_unit = unit;
- ifp->if_mtu = PPP_MRU;
+ 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";
- ifp->if_mediamtu = 1500;
+ 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
if (sp->flags & DBGLOG)
printf("if_ppp: created unit %d\n", unit);
} else {
- ifp->if_mtu = PPP_MRU;
+ ifp->if_mtu = PPP_MTU;
ifp->if_flags |= IFF_RUNNING;
}
break;
}
-/* For Digital UNIX, there's space set aside in the header mbuf
+#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;
+ snit_intr(ifp, mb, &nif);
+ }
+#endif
+
+/*
+ * For Digital UNIX, there's space set aside in the header mbuf
* for the interface info.
*
- * For Sun it's smuggled around via a pointer at the front of the mbuf
+ * For Sun it's smuggled around via a pointer at the front of the mbuf.
*/
#ifdef __osf__
mb->m_pkthdr.rcvif = ifp;
switch (dst->sa_family) {
case AF_INET:
proto = PPP_IP;
+#ifdef SNIT_SUPPORT
+ if (ifp->if_flags & IFF_PROMISC) {
+ struct nit_if nif;
+ struct mbuf *m;
+ int len;
+
+ for (len = 0, m = m0; m != NULL; m = m->m_next)
+ len += m->m_len;
+ nif.nif_header = (caddr_t) &snit_ehdr;
+ nif.nif_hdrlen = sizeof(snit_ehdr);
+ nif.nif_bodylen = len;
+ nif.nif_promisc = 0;
+ snit_intr(ifp, m0, &nif);
+ }
+#endif
break;
+
default:
m_freem(m0);
return EAFNOSUPPORT;
int s, error;
struct ifreq *ifr = (struct ifreq *) data;
struct ifaddr *ifa = (struct ifaddr *) data;
+ u_short mtu;
error = 0;
s = splimp();
case SIOCSIFMTU:
if ((error = NOTSUSER()) != 0)
break;
+#ifdef __osf__
+ /* this hack is necessary because ifioctl checks ifr_data
+ * in 4.0 and 5.0, but ifr_data and ifr_metric overlay each
+ * other in the definition of struct ifreq so pppd can't set both.
+ */
+ bcopy(ifr->ifr_data, &mtu, sizeof (u_short));
+ ifr->ifr_mtu = mtu;
+#endif
+
if (ifr->ifr_mtu < PPP_MINMTU || ifr->ifr_mtu > PPP_MAXMTU) {
error = EINVAL;
break;
}
}
-/* Digital UNIX doesn't allow for removing ifnet structures
- * from the list. Taking the i/f down from pppd will take
- * care of most of the stuff that this code intends to do
- * anyhow
+/*
+ * Digital UNIX doesn't allow for removing ifnet structures
+ * from the list. But then we're not using this as a loadable
+ * module anyway, so that's OK.
+ *
+ * Under SunOS, this should allow the module to be unloaded.
+ * Unfortunately, it doesn't seem to detach all the references,
+ * so your system may well crash after you unload this module :-(
*/
#ifndef __osf__