+#ifdef ULTRIX
+ openlog("pppd", LOG_PID);
+#else
+ openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
+ setlogmask(LOG_UPTO(LOG_INFO));
+#endif
+}
+
+/*
+ * Create a file containing our process ID.
+ */
+static void
+create_pidfile()
+{
+ FILE *pidfile;
+
+ slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
+ _PATH_VARRUN, ifname);
+ if ((pidfile = fopen(pidfilename, "w")) != NULL) {
+ fprintf(pidfile, "%d\n", getpid());
+ (void) fclose(pidfile);
+ } else {
+ error("Failed to create pid file %s: %m", pidfilename);
+ pidfilename[0] = 0;
+ }
+}
+
+static void
+create_linkpidfile()
+{
+ FILE *pidfile;
+
+ if (linkname[0] == 0)
+ return;
+ script_setenv("LINKNAME", linkname, 1);
+ slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid",
+ _PATH_VARRUN, linkname);
+ if ((pidfile = fopen(linkpidfile, "w")) != NULL) {
+ fprintf(pidfile, "%d\n", getpid());
+ if (ifname[0])
+ fprintf(pidfile, "%s\n", ifname);
+ (void) fclose(pidfile);
+ } else {
+ error("Failed to create pid file %s: %m", linkpidfile);
+ linkpidfile[0] = 0;
+ }
+}
+
+/*
+ * holdoff_end - called via a timeout when the holdoff period ends.
+ */
+static void
+holdoff_end(arg)
+ void *arg;
+{
+ new_phase(PHASE_DORMANT);
+}
+
+/* List of protocol names, to make our messages a little more informative. */
+struct protocol_list {
+ u_short proto;
+ const char *name;
+} protocol_list[] = {
+ { 0x21, "IP" },
+ { 0x23, "OSI Network Layer" },
+ { 0x25, "Xerox NS IDP" },
+ { 0x27, "DECnet Phase IV" },
+ { 0x29, "Appletalk" },
+ { 0x2b, "Novell IPX" },
+ { 0x2d, "VJ compressed TCP/IP" },
+ { 0x2f, "VJ uncompressed TCP/IP" },
+ { 0x31, "Bridging PDU" },
+ { 0x33, "Stream Protocol ST-II" },
+ { 0x35, "Banyan Vines" },
+ { 0x39, "AppleTalk EDDP" },
+ { 0x3b, "AppleTalk SmartBuffered" },
+ { 0x3d, "Multi-Link" },
+ { 0x3f, "NETBIOS Framing" },
+ { 0x41, "Cisco Systems" },
+ { 0x43, "Ascom Timeplex" },
+ { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
+ { 0x47, "DCA Remote Lan" },
+ { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
+ { 0x4b, "SNA over 802.2" },
+ { 0x4d, "SNA" },
+ { 0x4f, "IP6 Header Compression" },
+ { 0x6f, "Stampede Bridging" },
+ { 0xfb, "single-link compression" },
+ { 0xfd, "1st choice compression" },
+ { 0x0201, "802.1d Hello Packets" },
+ { 0x0203, "IBM Source Routing BPDU" },
+ { 0x0205, "DEC LANBridge100 Spanning Tree" },
+ { 0x0231, "Luxcom" },
+ { 0x0233, "Sigma Network Systems" },
+ { 0x8021, "Internet Protocol Control Protocol" },
+ { 0x8023, "OSI Network Layer Control Protocol" },
+ { 0x8025, "Xerox NS IDP Control Protocol" },
+ { 0x8027, "DECnet Phase IV Control Protocol" },
+ { 0x8029, "Appletalk Control Protocol" },
+ { 0x802b, "Novell IPX Control Protocol" },
+ { 0x8031, "Bridging NCP" },
+ { 0x8033, "Stream Protocol Control Protocol" },
+ { 0x8035, "Banyan Vines Control Protocol" },
+ { 0x803d, "Multi-Link Control Protocol" },
+ { 0x803f, "NETBIOS Framing Control Protocol" },
+ { 0x8041, "Cisco Systems Control Protocol" },
+ { 0x8043, "Ascom Timeplex" },
+ { 0x8045, "Fujitsu LBLB Control Protocol" },
+ { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
+ { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
+ { 0x804b, "SNA over 802.2 Control Protocol" },
+ { 0x804d, "SNA Control Protocol" },
+ { 0x804f, "IP6 Header Compression Control Protocol" },
+ { 0x006f, "Stampede Bridging Control Protocol" },
+ { 0x80fb, "Single Link Compression Control Protocol" },
+ { 0x80fd, "Compression Control Protocol" },
+ { 0xc021, "Link Control Protocol" },
+ { 0xc023, "Password Authentication Protocol" },
+ { 0xc025, "Link Quality Report" },
+ { 0xc027, "Shiva Password Authentication Protocol" },
+ { 0xc029, "CallBack Control Protocol (CBCP)" },
+ { 0xc081, "Container Control Protocol" },
+ { 0xc223, "Challenge Handshake Authentication Protocol" },
+ { 0xc281, "Proprietary Authentication Protocol" },
+ { 0, NULL },
+};
+
+/*
+ * protocol_name - find a name for a PPP protocol.
+ */
+const char *
+protocol_name(proto)
+ int proto;
+{
+ struct protocol_list *lp;
+
+ for (lp = protocol_list; lp->proto != 0; ++lp)
+ if (proto == lp->proto)
+ return lp->name;
+ return NULL;
+}
+
+/*
+ * get_input - called when incoming data is available.
+ */
+static void
+get_input()
+{
+ int len, i;
+ u_char *p;
+ u_short protocol;
+ struct protent *protp;
+
+ p = inpacket_buf; /* point to beginning of packet buffer */
+
+ len = read_packet(inpacket_buf);
+ if (len < 0)
+ return;
+
+ if (len == 0) {
+ notice("Modem hangup");
+ hungup = 1;
+ status = EXIT_HANGUP;
+ lcp_lowerdown(0); /* serial link is no longer available */
+ link_terminated(0);
+ return;
+ }
+
+ if (debug /*&& (debugflags & DBG_INPACKET)*/)
+ dbglog("rcvd %P", p, len);
+
+ if (len < PPP_HDRLEN) {
+ MAINDEBUG(("io(): Received short packet."));
+ return;
+ }
+
+ p += 2; /* Skip address and control */
+ GETSHORT(protocol, p);
+ len -= PPP_HDRLEN;