summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/os.c
diff options
context:
space:
mode:
authoramurai <amurai@FreeBSD.org>1995-01-31 06:29:58 +0000
committeramurai <amurai@FreeBSD.org>1995-01-31 06:29:58 +0000
commit21ef2761fd1e5a4beb483da8bddf767d36540dce (patch)
tree3aecd1251d1647032ad1455f304eaeeaab4987d0 /usr.sbin/ppp/os.c
parent0487956fcf018d602bfe99b0e3398c6f4d55680a (diff)
downloadFreeBSD-src-21ef2761fd1e5a4beb483da8bddf767d36540dce.zip
FreeBSD-src-21ef2761fd1e5a4beb483da8bddf767d36540dce.tar.gz
Diffstat (limited to 'usr.sbin/ppp/os.c')
-rw-r--r--usr.sbin/ppp/os.c341
1 files changed, 341 insertions, 0 deletions
diff --git a/usr.sbin/ppp/os.c b/usr.sbin/ppp/os.c
new file mode 100644
index 0000000..72da1c6
--- /dev/null
+++ b/usr.sbin/ppp/os.c
@@ -0,0 +1,341 @@
+/*
+ * PPP OS Layer Interface Module
+ *
+ * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the Internet Initiative Japan, Inc. The name of the
+ * IIJ may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ * $Id:$
+ *
+ * TODO:
+ */
+#include "fsm.h"
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/route.h>
+#if __FreeBSD__ >= 2
+#include <osreldate.h>
+#endif
+#if defined(__NetBSD__) || _BSDI_VERSION >= 199312 || __FreeBSD_version >=199412
+#include <sys/select.h>
+#endif
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_tun.h>
+#include <errno.h>
+#include "ipcp.h"
+#include "os.h"
+
+static struct ifaliasreq ifra;
+static struct ifreq ifrq;
+static struct in_addr oldmine, oldhis;
+static int linkup;
+
+#ifdef bsdi
+extern char *inet_ntoa();
+#endif
+extern void HangupModem();
+
+char *IfDevName;
+
+static int
+SetIpDevice(myaddr, hisaddr, netmask, updown)
+struct in_addr myaddr, hisaddr, netmask;
+int updown;
+{
+ struct sockaddr_in *sin;
+ int s;
+ int changeaddr = 0;
+ u_long mask, addr;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ perror("socket");
+ return(-1);
+ }
+
+ if (updown == 0) {
+ if (oldmine.s_addr == 0 && oldhis.s_addr == 0) {
+ return(0);
+ }
+ bzero(&ifra.ifra_addr, sizeof(ifra.ifra_addr));
+ bzero(&ifra.ifra_broadaddr, sizeof(ifra.ifra_addr));
+ bzero(&ifra.ifra_mask, sizeof(ifra.ifra_addr));
+#ifdef DEBUG
+ logprintf("DIFADDR\n");
+#endif
+ if (ioctl(s, SIOCDIFADDR, &ifra) < 0) {
+ perror("SIOCDIFADDR");
+ return(-1);
+ }
+
+ oldmine.s_addr = oldhis.s_addr = 0;
+ } else {
+ /*
+ * If given addresses are alreay set, then ignore this request.
+ */
+ if (oldmine.s_addr == myaddr.s_addr && oldhis.s_addr == hisaddr.s_addr)
+ return(0);
+ /*
+ * If different address has been set, then delete it first.
+ */
+ if (oldmine.s_addr || oldhis.s_addr) {
+ changeaddr = 1;
+ }
+ /*
+ * Set interface address
+ */
+ sin = (struct sockaddr_in *)&(ifra.ifra_addr);
+ sin->sin_family = AF_INET;
+ sin->sin_addr = oldmine = myaddr;
+ sin->sin_len = sizeof(*sin);
+ /*
+ * Set destination address
+ */
+ sin = (struct sockaddr_in *)&(ifra.ifra_broadaddr);
+ sin->sin_family = AF_INET;
+ sin->sin_addr = oldhis = hisaddr;
+ sin->sin_len = sizeof(*sin);
+ /*
+ */
+ addr = ntohl(myaddr.s_addr);
+ if (IN_CLASSA(addr))
+ mask = IN_CLASSA_NET;
+ else if (IN_CLASSB(addr))
+ mask = IN_CLASSB_NET;
+ else
+ mask = IN_CLASSC_NET;
+ /*
+ * if subnet mask is given, use it instead of class mask.
+ */
+ if (netmask.s_addr && (ntohl(netmask.s_addr) & mask) == mask)
+ mask = ntohl(netmask.s_addr);
+
+ sin = (struct sockaddr_in *)&(ifra.ifra_mask);
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = htonl(mask);
+ sin->sin_len = sizeof(*sin);
+
+ if (changeaddr) {
+ /*
+ * Interface already exists. Just change the address.
+ */
+ bcopy(&ifra.ifra_addr, &ifrq.ifr_addr, sizeof(struct sockaddr));
+ if (ioctl(s, SIOCSIFADDR, &ifra) < 0)
+ perror("SIFADDR");;
+ bcopy(&ifra.ifra_broadaddr, &ifrq.ifr_dstaddr, sizeof(struct sockaddr));
+ if (ioctl(s, SIOCSIFDSTADDR, &ifrq) < 0)
+ perror("SIFDSTADDR");;
+#ifdef notdef
+ bcopy(&ifra.ifra_mask, &ifrq.ifr_broadaddr, sizeof(struct sockaddr));
+ if (ioctl(s, SIOCSIFBRDADDR, &ifrq) < 0)
+ perror("SIFBRDADDR");
+#endif
+ } else if (ioctl(s, SIOCAIFADDR, &ifra) < 0) {
+ perror("SIOCAIFADDR");
+ return(-1);
+ }
+ }
+ close(s);
+ return(0);
+}
+
+int
+OsSetIpaddress(myaddr, hisaddr, netmask)
+struct in_addr myaddr, hisaddr, netmask;
+{
+ return(SetIpDevice(myaddr, hisaddr, netmask, 1));
+}
+
+static struct in_addr peer_addr;
+struct in_addr defaddr;
+
+void
+OsLinkup()
+{
+ char *s;
+
+ if (linkup == 0) {
+ if (setuid(0) < 0)
+ logprintf("setuid failed\n");
+ peer_addr = IpcpInfo.his_ipaddr;
+ s = (char *)inet_ntoa(peer_addr);
+ LogPrintf(LOG_PHASE, "OsLinkup: %s\n", s);
+
+ if (SelectSystem(inet_ntoa(IpcpInfo.want_ipaddr), LINKFILE) < 0) {
+ if (dstsystem) {
+ if (SelectSystem(dstsystem, LINKFILE) < 0)
+ SelectSystem("MYADDR", LINKFILE);
+ } else
+ SelectSystem("MYADDR", LINKFILE);
+ }
+ linkup = 1;
+ }
+}
+
+void
+OsLinkdown()
+{
+ char *s;
+
+ if (linkup) {
+ s = (char *)inet_ntoa(peer_addr);
+ LogPrintf(LOG_PHASE, "OsLinkdown: %s\n", s);
+ if (!(mode & MODE_AUTO))
+ DeleteIfRoutes(0);
+ linkup = 0;
+ }
+}
+
+int
+OsInterfaceDown(final)
+int final;
+{
+ struct in_addr zeroaddr;
+ int s;
+
+ OsLinkdown();
+ if (!final && (mode & MODE_AUTO)) /* We still want interface alive */
+ return(0);
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ perror("socket");
+ return(-1);
+ }
+ ifrq.ifr_flags &= ~IFF_UP;
+ if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
+ perror("SIOCSIFFLAGS");
+ close(s);
+ return(-1);
+ }
+
+ zeroaddr.s_addr = 0;
+ SetIpDevice(zeroaddr, zeroaddr, zeroaddr, 0);
+
+ close(s);
+ return(0);
+}
+
+void
+OsSetInterfaceParams(type, mtu, speed)
+int type, mtu, speed;
+{
+ struct tuninfo info;
+#if __FreeBSD__ >= 2
+ info.tif_type = type;
+ info.tif_mtu = mtu;
+ info.tif_baudrate = speed;
+#else
+ info.if_type = type;
+ info.if_mtu = mtu;
+ info.if_baudrate = speed;
+#endif
+ if (ioctl(tun_out, TUNSIFINFO, &info) < 0)
+ perror("TUNSIFINFO");
+}
+
+/*
+ * Open tunnel device and returns its descriptor
+ */
+int
+OpenTunnel(ptun)
+int *ptun;
+{
+ int s;
+ char *cp;
+ char *suffix = "0123456789";
+ char ifname[IFNAMSIZ];
+ char devname[12];
+
+ strcpy(devname, "/dev/tun0");
+ for (cp = suffix; *cp; cp++) {
+ devname[8] = *cp;
+ tun_out = open(devname, O_RDWR);
+ if (tun_out >= 0)
+ break;
+ }
+ *ptun = cp - suffix;
+ if (*cp == '\0') {
+ fprintf(stderr, "No tunnel device is available.\n");
+ return(-1);
+ }
+
+ /*
+ * At first, name the interface.
+ */
+ strcpy(ifname, devname + 5);
+
+ bzero((char *)&ifra, sizeof(ifra));
+ bzero((char *)&ifrq, sizeof(ifrq));
+
+ strncpy(ifrq.ifr_name, ifname, IFNAMSIZ);
+ strncpy(ifra.ifra_name, ifname, IFNAMSIZ);
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ perror("socket");
+ return(-1);
+ }
+
+ /*
+ * Now, bring up the interface.
+ */
+ if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
+ perror("SIOCGIFFLAGS");
+ close(s);
+ return(-1);
+ }
+
+ ifrq.ifr_flags |= IFF_UP;
+ if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
+ perror("SIOCSIFFLAGS");
+ close(s);
+ return(-1);
+ }
+
+ tun_in = tun_out;
+ IfDevName = devname + 5;
+ if (GetIfIndex(IfDevName) < 0) {
+ fprintf(stderr, "can't find ifindex.\n");
+ close(s);
+ return(-1);
+ }
+ printf("Using interface: %s\r\n", IfDevName);
+ LogPrintf(LOG_PHASE, "Using interface: %s\n", IfDevName);
+ close(s);
+ return(0);
+}
+
+void
+OsCloseLink(flag)
+int flag;
+{
+ HangupModem(flag);
+}
+
+void
+OsAddInOctets(cnt)
+int cnt;
+{
+}
+
+void
+OsAddOutOctets(cnt)
+int cnt;
+{
+}
+
OpenPOWER on IntegriCloud