forked from Imagelibrary/rtems
Added port of ppp-2.3.5 from Tomasz Domin <dot@comarch.pl> of ComArch SA.
Tomasz only tested this on the mpc823. The official site for the original source for this PPP implementation is: ftp://cs.anu.edu.au/pub/software/ppp NOTE: As of 11/30/1999, the current version of this source is 2.3.10.
This commit is contained in:
@@ -10,7 +10,7 @@ POSIX_SUBDIRS = rtems_webserver
|
||||
endif
|
||||
|
||||
SUBDIRS = include kern lib libc net netinet nfs rtems rtems_servers \
|
||||
$(POSIX_SUBDIRS) wrapup
|
||||
pppd $(POSIX_SUBDIRS) wrapup
|
||||
|
||||
EXTRA_DIST = \
|
||||
CHANGELOG \
|
||||
|
||||
183
c/src/exec/libnetworking/net/ppp_defs.h
Normal file
183
c/src/exec/libnetworking/net/ppp_defs.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* ppp_defs.h - PPP definitions.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _PPP_DEFS_H_
|
||||
#define _PPP_DEFS_H_
|
||||
|
||||
/*
|
||||
* The basic PPP frame.
|
||||
*/
|
||||
#define PPP_HDRLEN 4 /* octets for standard ppp header */
|
||||
#define PPP_FCSLEN 2 /* octets for FCS */
|
||||
|
||||
/*
|
||||
* Packet sizes
|
||||
*
|
||||
* Note - lcp shouldn't be allowed to negotiate stuff outside these
|
||||
* limits. See lcp.h in the pppd directory.
|
||||
* (XXX - these constants should simply be shared by lcp.c instead
|
||||
* of living in lcp.h)
|
||||
*/
|
||||
#define PPP_MTU 1500 /* Default MTU (size of Info field) */
|
||||
#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN)
|
||||
#define PPP_MINMTU 64
|
||||
#define PPP_MRU 1500 /* default MRU = max length of info field */
|
||||
#define PPP_MAXMRU 65000 /* Largest MRU we allow */
|
||||
#define PPP_MINMRU 128
|
||||
|
||||
#define PPP_ADDRESS(p) (((u_char *)(p))[0])
|
||||
#define PPP_CONTROL(p) (((u_char *)(p))[1])
|
||||
#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
|
||||
|
||||
/*
|
||||
* Significant octet values.
|
||||
*/
|
||||
#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */
|
||||
#define PPP_UI 0x03 /* Unnumbered Information */
|
||||
#define PPP_FLAG 0x7e /* Flag Sequence */
|
||||
#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */
|
||||
#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */
|
||||
|
||||
/*
|
||||
* Protocol field values.
|
||||
*/
|
||||
#define PPP_IP 0x21 /* Internet Protocol */
|
||||
#define PPP_AT 0x29 /* AppleTalk Protocol */
|
||||
#define PPP_IPX 0x2b /* IPX protocol */
|
||||
#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
|
||||
#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
|
||||
#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
|
||||
#define PPP_COMP 0xfd /* compressed packet */
|
||||
#define PPP_IPCP 0x8021 /* IP Control Protocol */
|
||||
#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
|
||||
#define PPP_IPXCP 0x802b /* IPX Control Protocol */
|
||||
#define PPP_CCP 0x80fd /* Compression Control Protocol */
|
||||
#define PPP_LCP 0xc021 /* Link Control Protocol */
|
||||
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
|
||||
#define PPP_LQR 0xc025 /* Link Quality Report protocol */
|
||||
#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
|
||||
#define PPP_CBCP 0xc029 /* Callback Control Protocol */
|
||||
|
||||
/*
|
||||
* Values for FCS calculations.
|
||||
*/
|
||||
#define PPP_INITFCS 0xffff /* Initial FCS value */
|
||||
#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */
|
||||
#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
|
||||
|
||||
/*
|
||||
* A 32-bit unsigned integral type.
|
||||
*/
|
||||
|
||||
#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \
|
||||
&& !defined(__FreeBSD__) && (NS_TARGET < 40) && !defined(__rtems__)
|
||||
#ifdef UINT32_T
|
||||
typedef UINT32_T u_int32_t;
|
||||
#else
|
||||
typedef unsigned int u_int32_t;
|
||||
typedef unsigned short u_int16_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Extended asyncmap - allows any character to be escaped.
|
||||
*/
|
||||
typedef u_int32_t ext_accm[8];
|
||||
|
||||
/*
|
||||
* What to do with network protocol (NP) packets.
|
||||
*/
|
||||
enum NPmode {
|
||||
NPMODE_PASS, /* pass the packet through */
|
||||
NPMODE_DROP, /* silently drop the packet */
|
||||
NPMODE_ERROR, /* return an error */
|
||||
NPMODE_QUEUE /* save it up for later. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Statistics.
|
||||
*/
|
||||
struct pppstat {
|
||||
unsigned int ppp_ibytes; /* bytes received */
|
||||
unsigned int ppp_ipackets; /* packets received */
|
||||
unsigned int ppp_ierrors; /* receive errors */
|
||||
unsigned int ppp_obytes; /* bytes sent */
|
||||
unsigned int ppp_opackets; /* packets sent */
|
||||
unsigned int ppp_oerrors; /* transmit errors */
|
||||
};
|
||||
|
||||
struct vjstat {
|
||||
unsigned int vjs_packets; /* outbound packets */
|
||||
unsigned int vjs_compressed; /* outbound compressed packets */
|
||||
unsigned int vjs_searches; /* searches for connection state */
|
||||
unsigned int vjs_misses; /* times couldn't find conn. state */
|
||||
unsigned int vjs_uncompressedin; /* inbound uncompressed packets */
|
||||
unsigned int vjs_compressedin; /* inbound compressed packets */
|
||||
unsigned int vjs_errorin; /* inbound unknown type packets */
|
||||
unsigned int vjs_tossed; /* inbound packets tossed because of error */
|
||||
};
|
||||
|
||||
struct ppp_stats {
|
||||
struct pppstat p; /* basic PPP statistics */
|
||||
struct vjstat vj; /* VJ header compression statistics */
|
||||
};
|
||||
|
||||
struct compstat {
|
||||
unsigned int unc_bytes; /* total uncompressed bytes */
|
||||
unsigned int unc_packets; /* total uncompressed packets */
|
||||
unsigned int comp_bytes; /* compressed bytes */
|
||||
unsigned int comp_packets; /* compressed packets */
|
||||
unsigned int inc_bytes; /* incompressible bytes */
|
||||
unsigned int inc_packets; /* incompressible packets */
|
||||
unsigned int ratio; /* recent compression ratio << 8 */
|
||||
};
|
||||
|
||||
struct ppp_comp_stats {
|
||||
struct compstat c; /* packet compression statistics */
|
||||
struct compstat d; /* packet decompression statistics */
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure records the time in seconds since
|
||||
* the last NP packet was sent or received.
|
||||
*/
|
||||
struct ppp_idle {
|
||||
time_t xmit_idle; /* time since last NP packet sent */
|
||||
time_t recv_idle; /* time since last NP packet received */
|
||||
};
|
||||
|
||||
#ifndef __P
|
||||
#ifdef __STDC__
|
||||
#define __P(x) x
|
||||
#else
|
||||
#define __P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _PPP_DEFS_H_ */
|
||||
@@ -174,9 +174,10 @@ CODE facilitynames[] = {
|
||||
#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
|
||||
#define LOG_PERROR 0x20 /* log to stderr as well */
|
||||
|
||||
/*
|
||||
#ifdef KERNEL
|
||||
|
||||
#else /* not KERNEL */
|
||||
#else not KERNEL */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdarg.h>
|
||||
@@ -189,6 +190,6 @@ void syslog __P((int, const char *, ...));
|
||||
void vsyslog __P((int, const char *, va_list));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !KERNEL */
|
||||
/* #endif !KERNEL */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ POSIX_SUBDIRS = rtems_webserver
|
||||
endif
|
||||
|
||||
SUBDIRS = include kern lib libc net netinet nfs rtems rtems_servers \
|
||||
$(POSIX_SUBDIRS) wrapup
|
||||
pppd $(POSIX_SUBDIRS) wrapup
|
||||
|
||||
EXTRA_DIST = \
|
||||
CHANGELOG \
|
||||
|
||||
@@ -49,6 +49,7 @@ libc/Makefile
|
||||
net/Makefile
|
||||
netinet/Makefile
|
||||
nfs/Makefile
|
||||
pppd/Makefile
|
||||
rtems/Makefile
|
||||
rtems_servers/Makefile
|
||||
rtems_webserver/Makefile
|
||||
|
||||
@@ -33,8 +33,8 @@ MACHINE_H_FILES = $(MACHINE_H_PIECES:%=$(srcdir)/../machine/%.h)
|
||||
VM_H_PIECES = vm vm_extern vm_kern vm_param
|
||||
VM_H_FILES = $(VM_H_PIECES:%=$(srcdir)/../vm/%.h)
|
||||
|
||||
NET_H_PIECES = bpf ethernet if if_arp if_dl if_llc if_types netisr radix \
|
||||
raw_cb route
|
||||
NET_H_PIECES = bpf ethernet if if_arp if_dl if_llc if_ppp if_types netisr \
|
||||
ppp-comp ppp_defs radix raw_cb route
|
||||
NET_H_FILES = $(NET_H_PIECES:%=$(srcdir)/../net/%.h)
|
||||
|
||||
NETINET_H_PIECES = icmp_var if_ether igmp igmp_var in in_pcb in_systm in_var \
|
||||
|
||||
183
c/src/libnetworking/net/ppp_defs.h
Normal file
183
c/src/libnetworking/net/ppp_defs.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* ppp_defs.h - PPP definitions.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _PPP_DEFS_H_
|
||||
#define _PPP_DEFS_H_
|
||||
|
||||
/*
|
||||
* The basic PPP frame.
|
||||
*/
|
||||
#define PPP_HDRLEN 4 /* octets for standard ppp header */
|
||||
#define PPP_FCSLEN 2 /* octets for FCS */
|
||||
|
||||
/*
|
||||
* Packet sizes
|
||||
*
|
||||
* Note - lcp shouldn't be allowed to negotiate stuff outside these
|
||||
* limits. See lcp.h in the pppd directory.
|
||||
* (XXX - these constants should simply be shared by lcp.c instead
|
||||
* of living in lcp.h)
|
||||
*/
|
||||
#define PPP_MTU 1500 /* Default MTU (size of Info field) */
|
||||
#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN)
|
||||
#define PPP_MINMTU 64
|
||||
#define PPP_MRU 1500 /* default MRU = max length of info field */
|
||||
#define PPP_MAXMRU 65000 /* Largest MRU we allow */
|
||||
#define PPP_MINMRU 128
|
||||
|
||||
#define PPP_ADDRESS(p) (((u_char *)(p))[0])
|
||||
#define PPP_CONTROL(p) (((u_char *)(p))[1])
|
||||
#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
|
||||
|
||||
/*
|
||||
* Significant octet values.
|
||||
*/
|
||||
#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */
|
||||
#define PPP_UI 0x03 /* Unnumbered Information */
|
||||
#define PPP_FLAG 0x7e /* Flag Sequence */
|
||||
#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */
|
||||
#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */
|
||||
|
||||
/*
|
||||
* Protocol field values.
|
||||
*/
|
||||
#define PPP_IP 0x21 /* Internet Protocol */
|
||||
#define PPP_AT 0x29 /* AppleTalk Protocol */
|
||||
#define PPP_IPX 0x2b /* IPX protocol */
|
||||
#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
|
||||
#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
|
||||
#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
|
||||
#define PPP_COMP 0xfd /* compressed packet */
|
||||
#define PPP_IPCP 0x8021 /* IP Control Protocol */
|
||||
#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
|
||||
#define PPP_IPXCP 0x802b /* IPX Control Protocol */
|
||||
#define PPP_CCP 0x80fd /* Compression Control Protocol */
|
||||
#define PPP_LCP 0xc021 /* Link Control Protocol */
|
||||
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
|
||||
#define PPP_LQR 0xc025 /* Link Quality Report protocol */
|
||||
#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
|
||||
#define PPP_CBCP 0xc029 /* Callback Control Protocol */
|
||||
|
||||
/*
|
||||
* Values for FCS calculations.
|
||||
*/
|
||||
#define PPP_INITFCS 0xffff /* Initial FCS value */
|
||||
#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */
|
||||
#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
|
||||
|
||||
/*
|
||||
* A 32-bit unsigned integral type.
|
||||
*/
|
||||
|
||||
#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \
|
||||
&& !defined(__FreeBSD__) && (NS_TARGET < 40) && !defined(__rtems__)
|
||||
#ifdef UINT32_T
|
||||
typedef UINT32_T u_int32_t;
|
||||
#else
|
||||
typedef unsigned int u_int32_t;
|
||||
typedef unsigned short u_int16_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Extended asyncmap - allows any character to be escaped.
|
||||
*/
|
||||
typedef u_int32_t ext_accm[8];
|
||||
|
||||
/*
|
||||
* What to do with network protocol (NP) packets.
|
||||
*/
|
||||
enum NPmode {
|
||||
NPMODE_PASS, /* pass the packet through */
|
||||
NPMODE_DROP, /* silently drop the packet */
|
||||
NPMODE_ERROR, /* return an error */
|
||||
NPMODE_QUEUE /* save it up for later. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Statistics.
|
||||
*/
|
||||
struct pppstat {
|
||||
unsigned int ppp_ibytes; /* bytes received */
|
||||
unsigned int ppp_ipackets; /* packets received */
|
||||
unsigned int ppp_ierrors; /* receive errors */
|
||||
unsigned int ppp_obytes; /* bytes sent */
|
||||
unsigned int ppp_opackets; /* packets sent */
|
||||
unsigned int ppp_oerrors; /* transmit errors */
|
||||
};
|
||||
|
||||
struct vjstat {
|
||||
unsigned int vjs_packets; /* outbound packets */
|
||||
unsigned int vjs_compressed; /* outbound compressed packets */
|
||||
unsigned int vjs_searches; /* searches for connection state */
|
||||
unsigned int vjs_misses; /* times couldn't find conn. state */
|
||||
unsigned int vjs_uncompressedin; /* inbound uncompressed packets */
|
||||
unsigned int vjs_compressedin; /* inbound compressed packets */
|
||||
unsigned int vjs_errorin; /* inbound unknown type packets */
|
||||
unsigned int vjs_tossed; /* inbound packets tossed because of error */
|
||||
};
|
||||
|
||||
struct ppp_stats {
|
||||
struct pppstat p; /* basic PPP statistics */
|
||||
struct vjstat vj; /* VJ header compression statistics */
|
||||
};
|
||||
|
||||
struct compstat {
|
||||
unsigned int unc_bytes; /* total uncompressed bytes */
|
||||
unsigned int unc_packets; /* total uncompressed packets */
|
||||
unsigned int comp_bytes; /* compressed bytes */
|
||||
unsigned int comp_packets; /* compressed packets */
|
||||
unsigned int inc_bytes; /* incompressible bytes */
|
||||
unsigned int inc_packets; /* incompressible packets */
|
||||
unsigned int ratio; /* recent compression ratio << 8 */
|
||||
};
|
||||
|
||||
struct ppp_comp_stats {
|
||||
struct compstat c; /* packet compression statistics */
|
||||
struct compstat d; /* packet decompression statistics */
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure records the time in seconds since
|
||||
* the last NP packet was sent or received.
|
||||
*/
|
||||
struct ppp_idle {
|
||||
time_t xmit_idle; /* time since last NP packet sent */
|
||||
time_t recv_idle; /* time since last NP packet received */
|
||||
};
|
||||
|
||||
#ifndef __P
|
||||
#ifdef __STDC__
|
||||
#define __P(x) x
|
||||
#else
|
||||
#define __P(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _PPP_DEFS_H_ */
|
||||
60
c/src/libnetworking/pppd/Makefile.in
Normal file
60
c/src/libnetworking/pppd/Makefile.in
Normal file
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
@SET_MAKE@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = ..
|
||||
subdir = pppd
|
||||
|
||||
RTEMS_ROOT = @RTEMS_ROOT@
|
||||
PROJECT_ROOT = @PROJECT_ROOT@
|
||||
|
||||
VPATH = @srcdir@
|
||||
|
||||
LIBNAME = lib.a
|
||||
LIB = ${ARCH}/${LIBNAME}
|
||||
|
||||
# C and C++ source names, if any, go here -- minus the .c or .cc
|
||||
# What to do about main.c?
|
||||
C_PIECES = auth cbcp ccp chap chap_ms chat demand fsm ipcp \
|
||||
ipxcp lcp magic options upap md4 md5 rtems-ppp
|
||||
C_FILES = $(C_PIECES:%=%.c)
|
||||
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
|
||||
|
||||
SRCS = $(C_FILES)
|
||||
OBJS = $(C_O_FILES)
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(RTEMS_ROOT)/make/lib.cfg
|
||||
|
||||
INSTALL_CHANGE = @INSTALL_CHANGE@
|
||||
|
||||
#
|
||||
# Add local stuff here using +=
|
||||
#
|
||||
|
||||
# DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS -DDIAGNOSTIC \
|
||||
# -DBOOTP_COMPAT
|
||||
CPPFLAGS +=
|
||||
CFLAGS +=
|
||||
|
||||
#
|
||||
# Add your list of files to delete here. The config files
|
||||
# already know how to delete some stuff, so you may want
|
||||
# to just run 'make clean' first to see what gets missed.
|
||||
# 'make clobber' already includes 'make clean'
|
||||
#
|
||||
|
||||
CLEAN_ADDITIONS += $(LIB)
|
||||
CLOBBER_ADDITIONS +=
|
||||
|
||||
all: ${ARCH} $(LIB)
|
||||
|
||||
$(LIB): $(SRCS) ${OBJS}
|
||||
$(make-library)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
13
c/src/libnetworking/pppd/README
Normal file
13
c/src/libnetworking/pppd/README
Normal file
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
This directory contains a port of ppp-2.3.5. The official site for
|
||||
the original source for this PPP implementation is:
|
||||
|
||||
ftp://cs.anu.edu.au/pub/software/ppp
|
||||
|
||||
NOTE: As of 11/30/1999, the current version of this source is 2.3.10.
|
||||
|
||||
The port was performed by Tomasz Domin <dot@comarch.pl> of ComArch SA
|
||||
and has only been tested on the mpc823.
|
||||
27
c/src/libnetworking/pppd/STATUS
Normal file
27
c/src/libnetworking/pppd/STATUS
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
Overall, this code should still be considered in its early stages. It
|
||||
works but has some distance to go before it is fully documented and
|
||||
easily configurable.
|
||||
|
||||
+ Compare the code to the original 2.3.5 and eliminate spurious changes.
|
||||
|
||||
+ Update the code to 2.3.10.
|
||||
|
||||
+ Eliminate items specific to Tomasz' system. In particular, the
|
||||
code reports status and gets configuration information in a system
|
||||
specific manner. main.c is particularly guilty of this although
|
||||
other files suffer from this also.
|
||||
|
||||
+ Find comments in Polish and get Tomasz to translate them. :)
|
||||
|
||||
+ Add netdemo showing configuration and initialization.
|
||||
|
||||
+ Get feature list.
|
||||
|
||||
+ Document dialer setup.
|
||||
|
||||
+ Only modem driver is system specific so there is the possibility
|
||||
that shareable code exists in it.
|
||||
843
c/src/libnetworking/pppd/auth.c
Normal file
843
c/src/libnetworking/pppd/auth.c
Normal file
@@ -0,0 +1,843 @@
|
||||
/*
|
||||
* auth.c - PPP authentication and phase control.
|
||||
*
|
||||
* Copyright (c) 1993 The Australian National University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Australian National University. The name of the University
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#if defined(_PATH_LASTLOG) && defined(_linux_)
|
||||
#include <lastlog.h>
|
||||
#endif
|
||||
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
/* #include <stbconfig.h> */
|
||||
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ipcp.h"
|
||||
#include "upap.h"
|
||||
#include "chap.h"
|
||||
#ifdef CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
#include "pathnames.h"
|
||||
|
||||
/* Used for storing a sequence of words. Usually malloced. */
|
||||
struct wordlist {
|
||||
struct wordlist *next;
|
||||
char word[1];
|
||||
};
|
||||
|
||||
/* Bits in scan_authfile return value */
|
||||
#define NONWILD_SERVER 1
|
||||
#define NONWILD_CLIENT 2
|
||||
|
||||
#define ISWILD(word) (word[0] == '*' && word[1] == 0)
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* The name by which the peer authenticated itself to us. */
|
||||
char peer_authname[MAXNAMELEN];
|
||||
|
||||
/* Records which authentication operations haven't completed yet. */
|
||||
static int auth_pending[NUM_PPP];
|
||||
|
||||
/* Set if we have successfully called plogin() */
|
||||
static int logged_in;
|
||||
|
||||
/* Set if we have run the /etc/ppp/auth-up script. */
|
||||
static int did_authup;
|
||||
|
||||
/* List of addresses which the peer may use. */
|
||||
static struct wordlist *addresses[NUM_PPP];
|
||||
|
||||
/* Number of network protocols which we have opened. */
|
||||
static int num_np_open;
|
||||
|
||||
/* Number of network protocols which have come up. */
|
||||
static int num_np_up;
|
||||
|
||||
/* Set if we got the contents of passwd[] from the pap-secrets file. */
|
||||
static int passwd_from_file;
|
||||
|
||||
/* Bits in auth_pending[] */
|
||||
#define PAP_WITHPEER 1
|
||||
#define PAP_PEER 2
|
||||
#define CHAP_WITHPEER 4
|
||||
#define CHAP_PEER 8
|
||||
|
||||
extern char *crypt __P((const char *, const char *));
|
||||
|
||||
/* Prototypes for procedures local to this file. */
|
||||
|
||||
static void network_phase __P((int));
|
||||
static void check_idle __P((void *));
|
||||
static void connect_time_expired __P((void *));
|
||||
static int plogin __P((char *, char *, char **, int *));
|
||||
static void plogout __P((void));
|
||||
static int null_login __P((int));
|
||||
static int get_pap_passwd __P((char *));
|
||||
static int have_pap_secret __P((void));
|
||||
static int have_chap_secret __P((char *, char *, u_int32_t));
|
||||
static int ip_addr_check __P((u_int32_t, struct wordlist *));
|
||||
static int scan_authfile __P((FILE *, char *, char *, u_int32_t, char *,
|
||||
struct wordlist **, char *));
|
||||
static void free_wordlist __P((struct wordlist *));
|
||||
static void auth_script __P((char *));
|
||||
static void set_allowed_addrs __P((int, struct wordlist *));
|
||||
|
||||
/*
|
||||
* An Open on LCP has requested a change from Dead to Establish phase.
|
||||
* Do what's necessary to bring the physical layer up.
|
||||
*/
|
||||
void
|
||||
link_required(unit)
|
||||
int unit;
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* LCP has terminated the link; go to the Dead phase and take the
|
||||
* physical layer down.
|
||||
*/
|
||||
void
|
||||
link_terminated(unit)
|
||||
int unit;
|
||||
{
|
||||
if (phase == PHASE_DEAD)
|
||||
return;
|
||||
if (logged_in)
|
||||
plogout();
|
||||
phase = PHASE_DEAD;
|
||||
syslog(LOG_NOTICE, "Connection terminated.");
|
||||
}
|
||||
|
||||
/*
|
||||
* LCP has gone down; it will either die or try to re-establish.
|
||||
*/
|
||||
void
|
||||
link_down(unit)
|
||||
int unit;
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
did_authup = 0;
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i) {
|
||||
if (!protp->enabled_flag)
|
||||
continue;
|
||||
if (protp->protocol != PPP_LCP && protp->lowerdown != NULL)
|
||||
(*protp->lowerdown)(unit);
|
||||
if (protp->protocol < 0xC000 && protp->close != NULL)
|
||||
(*protp->close)(unit, "LCP down");
|
||||
}
|
||||
num_np_open = 0;
|
||||
num_np_up = 0;
|
||||
if (phase != PHASE_DEAD)
|
||||
phase = PHASE_TERMINATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The link is established.
|
||||
* Proceed to the Dead, Authenticate or Network phase as appropriate.
|
||||
*/
|
||||
void
|
||||
link_established(unit)
|
||||
int unit;
|
||||
{
|
||||
int auth;
|
||||
lcp_options *wo = &lcp_wantoptions[unit];
|
||||
lcp_options *go = &lcp_gotoptions[unit];
|
||||
lcp_options *ho = &lcp_hisoptions[unit];
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
/*
|
||||
* Tell higher-level protocols that LCP is up.
|
||||
*/
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if (protp->protocol != PPP_LCP && protp->enabled_flag
|
||||
&& protp->lowerup != NULL)
|
||||
(*protp->lowerup)(unit);
|
||||
|
||||
if (auth_required && !(go->neg_chap || go->neg_upap)) {
|
||||
/*
|
||||
* We wanted the peer to authenticate itself, and it refused:
|
||||
* treat it as though it authenticated with PAP using a username
|
||||
* of "" and a password of "". If that's not OK, boot it out.
|
||||
*/
|
||||
if (!wo->neg_upap || !null_login(unit)) {
|
||||
lcp_close(unit, "peer refused to authenticate");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
phase = PHASE_AUTHENTICATE;
|
||||
auth = 0;
|
||||
if (go->neg_chap) {
|
||||
ChapAuthPeer(unit, our_name, go->chap_mdtype);
|
||||
auth |= CHAP_PEER;
|
||||
} else if (go->neg_upap) {
|
||||
upap_authpeer(unit);
|
||||
auth |= PAP_PEER;
|
||||
}
|
||||
if (ho->neg_chap) {
|
||||
ChapAuthWithPeer(unit, user, ho->chap_mdtype);
|
||||
auth |= CHAP_WITHPEER;
|
||||
} else if (ho->neg_upap) {
|
||||
if (passwd[0] == 0) {
|
||||
passwd_from_file = 1;
|
||||
get_pap_passwd(passwd);
|
||||
}
|
||||
upap_authwithpeer(unit, user, passwd);
|
||||
auth |= PAP_WITHPEER;
|
||||
}
|
||||
auth_pending[unit] = auth;
|
||||
|
||||
if (!auth)
|
||||
network_phase(unit);
|
||||
}
|
||||
|
||||
/*
|
||||
* Proceed to the network phase.
|
||||
*/
|
||||
static void
|
||||
network_phase(unit)
|
||||
int unit;
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
lcp_options *go = &lcp_gotoptions[unit];
|
||||
|
||||
/*
|
||||
* If the peer had to authenticate, run the auth-up script now.
|
||||
*/
|
||||
if ((go->neg_chap || go->neg_upap) && !did_authup) {
|
||||
auth_script(_PATH_AUTHUP);
|
||||
did_authup = 1;
|
||||
}
|
||||
|
||||
#ifdef CBCP_SUPPORT
|
||||
/*
|
||||
* If we negotiated callback, do it now.
|
||||
*/
|
||||
if (go->neg_cbcp) {
|
||||
phase = PHASE_CALLBACK;
|
||||
(*cbcp_protent.open)(unit);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
phase = PHASE_NETWORK;
|
||||
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if (protp->protocol < 0xC000 && protp->enabled_flag
|
||||
&& protp->open != NULL) {
|
||||
(*protp->open)(unit);
|
||||
if (protp->protocol != PPP_CCP)
|
||||
++num_np_open;
|
||||
}
|
||||
|
||||
if (num_np_open == 0)
|
||||
/* nothing to do */
|
||||
lcp_close(0, "No network protocols running");
|
||||
}
|
||||
|
||||
/*
|
||||
* The peer has failed to authenticate himself using `protocol'.
|
||||
*/
|
||||
void
|
||||
auth_peer_fail(unit, protocol)
|
||||
int unit, protocol;
|
||||
{
|
||||
/*
|
||||
* Authentication failure: take the link down
|
||||
*/
|
||||
lcp_close(unit, "Authentication failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* The peer has been successfully authenticated using `protocol'.
|
||||
*/
|
||||
void
|
||||
auth_peer_success(unit, protocol, name, namelen)
|
||||
int unit, protocol;
|
||||
char *name;
|
||||
int namelen;
|
||||
{
|
||||
int bit;
|
||||
|
||||
switch (protocol) {
|
||||
case PPP_CHAP:
|
||||
bit = CHAP_PEER;
|
||||
break;
|
||||
case PPP_PAP:
|
||||
bit = PAP_PEER;
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x",
|
||||
protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the authenticated name of the peer for later.
|
||||
*/
|
||||
if (namelen > sizeof(peer_authname) - 1)
|
||||
namelen = sizeof(peer_authname) - 1;
|
||||
BCOPY(name, peer_authname, namelen);
|
||||
peer_authname[namelen] = 0;
|
||||
/*
|
||||
* If there is no more authentication still to be done,
|
||||
* proceed to the network (or callback) phase.
|
||||
*/
|
||||
if ((auth_pending[unit] &= ~bit) == 0)
|
||||
network_phase(unit);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have failed to authenticate ourselves to the peer using `protocol'.
|
||||
*/
|
||||
void
|
||||
auth_withpeer_fail(unit, protocol)
|
||||
int unit, protocol;
|
||||
{
|
||||
if (passwd_from_file)
|
||||
BZERO(passwd, MAXSECRETLEN);
|
||||
/*
|
||||
* We've failed to authenticate ourselves to our peer.
|
||||
* He'll probably take the link down, and there's not much
|
||||
* we can do except wait for that.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* We have successfully authenticated ourselves with the peer using `protocol'.
|
||||
*/
|
||||
void
|
||||
auth_withpeer_success(unit, protocol)
|
||||
int unit, protocol;
|
||||
{
|
||||
int bit;
|
||||
|
||||
switch (protocol) {
|
||||
case PPP_CHAP:
|
||||
bit = CHAP_WITHPEER;
|
||||
break;
|
||||
case PPP_PAP:
|
||||
if (passwd_from_file)
|
||||
BZERO(passwd, MAXSECRETLEN);
|
||||
bit = PAP_WITHPEER;
|
||||
break;
|
||||
default:
|
||||
|
||||
bit = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no more authentication still being done,
|
||||
* proceed to the network (or callback) phase.
|
||||
*/
|
||||
if ((auth_pending[unit] &= ~bit) == 0)
|
||||
network_phase(unit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* np_up - a network protocol has come up.
|
||||
*/
|
||||
void
|
||||
np_up(unit, proto)
|
||||
int unit, proto;
|
||||
{
|
||||
if (num_np_up == 0) {
|
||||
/*
|
||||
* At this point we consider that the link has come up successfully.
|
||||
*/
|
||||
need_holdoff = 0;
|
||||
|
||||
if (idle_time_limit > 0)
|
||||
TIMEOUT(check_idle, NULL, idle_time_limit);
|
||||
|
||||
/*
|
||||
* Set a timeout to close the connection once the maximum
|
||||
* connect time has expired.
|
||||
*/
|
||||
if (maxconnect > 0)
|
||||
TIMEOUT(connect_time_expired, 0, maxconnect);
|
||||
|
||||
/*
|
||||
* Detach now, if the updetach option was given.
|
||||
*/
|
||||
if (nodetach == -1)
|
||||
detach();
|
||||
}
|
||||
++num_np_up;
|
||||
}
|
||||
|
||||
/*
|
||||
* np_down - a network protocol has gone down.
|
||||
*/
|
||||
void
|
||||
np_down(unit, proto)
|
||||
int unit, proto;
|
||||
{
|
||||
if (--num_np_up == 0 && idle_time_limit > 0) {
|
||||
UNTIMEOUT(check_idle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* np_finished - a network protocol has finished using the link.
|
||||
*/
|
||||
void
|
||||
np_finished(unit, proto)
|
||||
int unit, proto;
|
||||
{
|
||||
if (--num_np_open <= 0) {
|
||||
/* no further use for the link: shut up shop. */
|
||||
lcp_close(0, "No network protocols running");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_idle - check whether the link has been idle for long
|
||||
* enough that we can shut it down.
|
||||
*/
|
||||
static void
|
||||
check_idle(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct ppp_idle idle;
|
||||
time_t itime;
|
||||
|
||||
if (!get_idle_time(0, &idle))
|
||||
return;
|
||||
itime = MIN(idle.xmit_idle, idle.recv_idle);
|
||||
if (itime >= idle_time_limit) {
|
||||
/* link is idle: shut it down. */
|
||||
syslog(LOG_INFO, "Terminating connection due to lack of activity.");
|
||||
lcp_close(0, "Link inactive");
|
||||
} else {
|
||||
TIMEOUT(check_idle, NULL, idle_time_limit - itime);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* connect_time_expired - log a message and close the connection.
|
||||
*/
|
||||
static void
|
||||
connect_time_expired(arg)
|
||||
void *arg;
|
||||
{
|
||||
syslog(LOG_INFO, "Connect time expired");
|
||||
lcp_close(0, "Connect time expired"); /* Close connection */
|
||||
}
|
||||
|
||||
/*
|
||||
* auth_check_options - called to check authentication options.
|
||||
*/
|
||||
void
|
||||
auth_check_options()
|
||||
{
|
||||
lcp_options *wo = &lcp_wantoptions[0];
|
||||
int can_auth;
|
||||
ipcp_options *ipwo = &ipcp_wantoptions[0];
|
||||
u_int32_t remote;
|
||||
|
||||
/* Default our_name to hostname, and user to our_name */
|
||||
if (our_name[0] == 0 || usehostname)
|
||||
strcpy(our_name, hostname);
|
||||
if (user[0] == 0)
|
||||
strcpy(user, our_name);
|
||||
|
||||
/* If authentication is required, ask peer for CHAP or PAP. */
|
||||
if (auth_required && !wo->neg_chap && !wo->neg_upap) {
|
||||
wo->neg_chap = 1;
|
||||
wo->neg_upap = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether we have appropriate secrets to use
|
||||
* to authenticate the peer.
|
||||
*/
|
||||
can_auth = wo->neg_upap && (uselogin || have_pap_secret());
|
||||
if (!can_auth && wo->neg_chap) {
|
||||
remote = ipwo->accept_remote? 0: ipwo->hisaddr;
|
||||
can_auth = have_chap_secret(remote_name, our_name, remote);
|
||||
}
|
||||
|
||||
if (auth_required && !can_auth) {
|
||||
option_error("peer authentication required but no suitable secret(s) found\n");
|
||||
if (remote_name[0] == 0)
|
||||
option_error("for authenticating any peer to us (%s)\n", our_name);
|
||||
else
|
||||
option_error("for authenticating peer %s to us (%s)\n",
|
||||
remote_name, our_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the user tried to override certain values
|
||||
* set by root.
|
||||
*/
|
||||
if (!auth_required && auth_req_info.priv > 0) {
|
||||
if (!default_device && devnam_info.priv == 0) {
|
||||
option_error("can't override device name when noauth option used");
|
||||
exit(1);
|
||||
}
|
||||
if ((connector != NULL && connector_info.priv == 0)
|
||||
|| (disconnector != NULL && disconnector_info.priv == 0)
|
||||
|| (welcomer != NULL && welcomer_info.priv == 0)) {
|
||||
option_error("can't override connect, disconnect or welcome");
|
||||
option_error("option values when noauth option used");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* auth_reset - called when LCP is starting negotiations to recheck
|
||||
* authentication options, i.e. whether we have appropriate secrets
|
||||
* to use for authenticating ourselves and/or the peer.
|
||||
*/
|
||||
void
|
||||
auth_reset(unit)
|
||||
int unit;
|
||||
{
|
||||
lcp_options *go = &lcp_gotoptions[unit];
|
||||
lcp_options *ao = &lcp_allowoptions[0];
|
||||
ipcp_options *ipwo = &ipcp_wantoptions[0];
|
||||
u_int32_t remote;
|
||||
|
||||
ao->neg_upap = !refuse_pap /*&& (passwd[0] != 0 || get_pap_passwd(NULL))*/;
|
||||
ao->neg_chap = !refuse_chap
|
||||
&& have_chap_secret(user, remote_name, (u_int32_t)0);
|
||||
|
||||
if (go->neg_upap && !uselogin && !have_pap_secret())
|
||||
go->neg_upap = 0;
|
||||
if (go->neg_chap) {
|
||||
remote = ipwo->accept_remote? 0: ipwo->hisaddr;
|
||||
if (!have_chap_secret(remote_name, our_name, remote))
|
||||
go->neg_chap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check_passwd - Check the user name and passwd against the PAP secrets
|
||||
* file. If requested, also check against the system password database,
|
||||
* and login the user if OK.
|
||||
*
|
||||
* returns:
|
||||
* UPAP_AUTHNAK: Authentication failed.
|
||||
* UPAP_AUTHACK: Authentication succeeded.
|
||||
* In either case, msg points to an appropriate message.
|
||||
*/
|
||||
int
|
||||
check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen)
|
||||
int unit;
|
||||
char *auser;
|
||||
int userlen;
|
||||
char *apasswd;
|
||||
int passwdlen;
|
||||
char **msg;
|
||||
int *msglen;
|
||||
{
|
||||
|
||||
|
||||
return UPAP_AUTHNAK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* plogin - Check the user name and password against the system
|
||||
* password database, and login the user if OK.
|
||||
*
|
||||
* returns:
|
||||
* UPAP_AUTHNAK: Login failed.
|
||||
* UPAP_AUTHACK: Login succeeded.
|
||||
* In either case, msg points to an appropriate message.
|
||||
*/
|
||||
|
||||
static int
|
||||
plogin(user, passwd, msg, msglen)
|
||||
char *user;
|
||||
char *passwd;
|
||||
char **msg;
|
||||
int *msglen;
|
||||
{
|
||||
syslog(LOG_INFO, "user %s logged in", user);
|
||||
logged_in = TRUE;
|
||||
|
||||
return (UPAP_AUTHACK);
|
||||
}
|
||||
|
||||
/*
|
||||
* plogout - Logout the user.
|
||||
*/
|
||||
static void
|
||||
plogout()
|
||||
{
|
||||
|
||||
logged_in = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* null_login - Check if a username of "" and a password of "" are
|
||||
* acceptable, and iff so, set the list of acceptable IP addresses
|
||||
* and return 1.
|
||||
*/
|
||||
static int
|
||||
null_login(unit)
|
||||
int unit;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_pap_passwd - get a password for authenticating ourselves with
|
||||
* our peer using PAP. Returns 1 on success, 0 if no suitable password
|
||||
* could be found.
|
||||
*/
|
||||
|
||||
static int
|
||||
get_pap_passwd(passwd)
|
||||
char *passwd;
|
||||
{
|
||||
#if 0
|
||||
/* XXX PPPConfiguration */
|
||||
GlobalSystemStatus *stat;
|
||||
stat=LockSTBSystemParam();
|
||||
strncpy(passwd, stat->PPP_Password, MAXSECRETLEN);
|
||||
UnlockSTBSystemParam();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* have_pap_secret - check whether we have a PAP file with any
|
||||
* secrets that we could possibly use for authenticating the peer.
|
||||
*/
|
||||
static int
|
||||
have_pap_secret()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* have_chap_secret - check whether we have a CHAP file with a
|
||||
* secret that we could possibly use for authenticating `client'
|
||||
* on `server'. Either can be the null string, meaning we don't
|
||||
* know the identity yet.
|
||||
*/
|
||||
static int
|
||||
have_chap_secret(client, server, remote)
|
||||
char *client;
|
||||
char *server;
|
||||
u_int32_t remote;
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_secret - open the CHAP secret file and return the secret
|
||||
* for authenticating the given client on the given server.
|
||||
* (We could be either client or server).
|
||||
*/
|
||||
int
|
||||
get_secret(unit, client, server, secret, secret_len, save_addrs)
|
||||
int unit;
|
||||
char *client;
|
||||
char *server;
|
||||
char *secret;
|
||||
int *secret_len;
|
||||
int save_addrs;
|
||||
{
|
||||
#if 0
|
||||
/* XXX PPPConfiguration */
|
||||
int len;
|
||||
GlobalSystemStatus *stat;
|
||||
stat=LockSTBSystemParam();
|
||||
len=strlen(stat->PPP_Password);
|
||||
strcpy( secret,stat->PPP_Password);
|
||||
UnlockSTBSystemParam();
|
||||
|
||||
*secret_len = len;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* set_allowed_addrs() - set the list of allowed addresses.
|
||||
*/
|
||||
static void
|
||||
set_allowed_addrs(unit, addrs)
|
||||
int unit;
|
||||
struct wordlist *addrs;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* auth_ip_addr - check whether the peer is authorized to use
|
||||
* a given IP address. Returns 1 if authorized, 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth_ip_addr(unit, addr)
|
||||
int unit;
|
||||
u_int32_t addr;
|
||||
{
|
||||
return ip_addr_check(addr, addresses[unit]);
|
||||
}
|
||||
|
||||
static int
|
||||
ip_addr_check(addr, addrs)
|
||||
u_int32_t addr;
|
||||
struct wordlist *addrs;
|
||||
{
|
||||
#if 0
|
||||
u_int32_t a, mask, ah;
|
||||
int accept;
|
||||
char *ptr_word, *ptr_mask;
|
||||
struct hostent *hp;
|
||||
struct netent *np;
|
||||
#endif
|
||||
|
||||
/* don't allow loopback or multicast address */
|
||||
if (bad_ip_adrs(addr))
|
||||
return 0;
|
||||
|
||||
if (addrs == NULL)
|
||||
return !auth_required; /* no addresses authorized */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* bad_ip_adrs - return 1 if the IP address is one we don't want
|
||||
* to use, such as an address in the loopback net or a multicast address.
|
||||
* addr is in network byte order.
|
||||
*/
|
||||
int
|
||||
bad_ip_adrs(addr)
|
||||
u_int32_t addr;
|
||||
{
|
||||
addr = ntohl(addr);
|
||||
return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
|
||||
|| IN_MULTICAST(addr) || IN_BADCLASS(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* check_access - complain if a secret file has too-liberal permissions.
|
||||
*/
|
||||
void
|
||||
check_access(f, filename)
|
||||
FILE *f;
|
||||
char *filename;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* scan_authfile - Scan an authorization file for a secret suitable
|
||||
* for authenticating `client' on `server'. The return value is -1
|
||||
* if no secret is found, otherwise >= 0. The return value has
|
||||
* NONWILD_CLIENT set if the secret didn't have "*" for the client, and
|
||||
* NONWILD_SERVER set if the secret didn't have "*" for the server.
|
||||
* Any following words on the line (i.e. address authorization
|
||||
* info) are placed in a wordlist and returned in *addrs.
|
||||
*/
|
||||
static int
|
||||
scan_authfile(f, client, server, ipaddr, secret, addrs, filename)
|
||||
FILE *f;
|
||||
char *client;
|
||||
char *server;
|
||||
u_int32_t ipaddr;
|
||||
char *secret;
|
||||
struct wordlist **addrs;
|
||||
char *filename;
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* free_wordlist - release memory allocated for a wordlist.
|
||||
*/
|
||||
static void
|
||||
free_wordlist(wp)
|
||||
struct wordlist *wp;
|
||||
{
|
||||
struct wordlist *next;
|
||||
|
||||
while (wp != NULL) {
|
||||
next = wp->next;
|
||||
free(wp);
|
||||
wp = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* auth_script - execute a script with arguments
|
||||
* interface-name peer-name real-user tty speed
|
||||
*/
|
||||
static void
|
||||
auth_script(script)
|
||||
char *script;
|
||||
{
|
||||
}
|
||||
431
c/src/libnetworking/pppd/cbcp.c
Normal file
431
c/src/libnetworking/pppd/cbcp.c
Normal file
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* cbcp - Call Back Configuration Protocol.
|
||||
*
|
||||
* Copyright (c) 1995 Pedro Roque Marques
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Pedro Roque Marques. The name of the author 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "cbcp.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ipcp.h"
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
static void cbcp_init __P((int unit));
|
||||
static void cbcp_open __P((int unit));
|
||||
static void cbcp_lowerup __P((int unit));
|
||||
static void cbcp_input __P((int unit, u_char *pkt, int len));
|
||||
static void cbcp_protrej __P((int unit));
|
||||
static int cbcp_printpkt __P((u_char *pkt, int len,
|
||||
void (*printer) __P((void *, char *, ...)),
|
||||
void *arg));
|
||||
|
||||
struct protent cbcp_protent = {
|
||||
PPP_CBCP,
|
||||
cbcp_init,
|
||||
cbcp_input,
|
||||
cbcp_protrej,
|
||||
cbcp_lowerup,
|
||||
NULL,
|
||||
cbcp_open,
|
||||
NULL,
|
||||
cbcp_printpkt,
|
||||
NULL,
|
||||
0,
|
||||
"CBCP",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
cbcp_state cbcp[NUM_PPP];
|
||||
|
||||
/* internal prototypes */
|
||||
|
||||
static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
|
||||
static void cbcp_resp __P((cbcp_state *us));
|
||||
static void cbcp_up __P((cbcp_state *us));
|
||||
static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
|
||||
static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
|
||||
|
||||
/* init state */
|
||||
static void
|
||||
cbcp_init(iface)
|
||||
int iface;
|
||||
{
|
||||
cbcp_state *us;
|
||||
|
||||
us = &cbcp[iface];
|
||||
memset(us, 0, sizeof(cbcp_state));
|
||||
us->us_unit = iface;
|
||||
us->us_type |= (1 << CB_CONF_NO);
|
||||
}
|
||||
|
||||
/* lower layer is up */
|
||||
static void
|
||||
cbcp_lowerup(iface)
|
||||
int iface;
|
||||
{
|
||||
cbcp_state *us = &cbcp[iface];
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "cbcp_lowerup");
|
||||
syslog(LOG_DEBUG, "want: %d", us->us_type);
|
||||
|
||||
if (us->us_type == CB_CONF_USER)
|
||||
syslog(LOG_DEBUG, "phone no: %s", us->us_number);
|
||||
}
|
||||
|
||||
static void
|
||||
cbcp_open(unit)
|
||||
int unit;
|
||||
{
|
||||
syslog(LOG_DEBUG, "cbcp_open");
|
||||
}
|
||||
|
||||
/* process an incomming packet */
|
||||
static void
|
||||
cbcp_input(unit, inpacket, pktlen)
|
||||
int unit;
|
||||
u_char *inpacket;
|
||||
int pktlen;
|
||||
{
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
u_short len;
|
||||
|
||||
cbcp_state *us = &cbcp[unit];
|
||||
|
||||
inp = inpacket;
|
||||
|
||||
if (pktlen < CBCP_MINLEN) {
|
||||
syslog(LOG_ERR, "CBCP packet is too small");
|
||||
return;
|
||||
}
|
||||
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
|
||||
#if 0
|
||||
if (len > pktlen) {
|
||||
syslog(LOG_ERR, "CBCP packet: invalid length");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
len -= CBCP_MINLEN;
|
||||
|
||||
switch(code) {
|
||||
case CBCP_REQ:
|
||||
us->us_id = id;
|
||||
cbcp_recvreq(us, inp, len);
|
||||
break;
|
||||
|
||||
case CBCP_RESP:
|
||||
syslog(LOG_DEBUG, "CBCP_RESP received");
|
||||
break;
|
||||
|
||||
case CBCP_ACK:
|
||||
if (id != us->us_id)
|
||||
syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d",
|
||||
us->us_id, id);
|
||||
|
||||
cbcp_recvack(us, inp, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* protocol was rejected by foe */
|
||||
void cbcp_protrej(int iface)
|
||||
{
|
||||
}
|
||||
|
||||
char *cbcp_codenames[] = {
|
||||
"Request", "Response", "Ack"
|
||||
};
|
||||
|
||||
char *cbcp_optionnames[] = {
|
||||
"NoCallback",
|
||||
"UserDefined",
|
||||
"AdminDefined",
|
||||
"List"
|
||||
};
|
||||
|
||||
/* pretty print a packet */
|
||||
static int
|
||||
cbcp_printpkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, opt, id, len, olen, delay;
|
||||
u_char *pstart;
|
||||
|
||||
if (plen < HEADERLEN)
|
||||
return 0;
|
||||
pstart = p;
|
||||
GETCHAR(code, p);
|
||||
GETCHAR(id, p);
|
||||
GETSHORT(len, p);
|
||||
if (len < HEADERLEN || len > plen)
|
||||
return 0;
|
||||
|
||||
if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
|
||||
printer(arg, " %s", cbcp_codenames[code-1]);
|
||||
else
|
||||
printer(arg, " code=0x%x", code);
|
||||
|
||||
printer(arg, " id=0x%x", id);
|
||||
len -= HEADERLEN;
|
||||
|
||||
switch (code) {
|
||||
case CBCP_REQ:
|
||||
case CBCP_RESP:
|
||||
case CBCP_ACK:
|
||||
while(len >= 2) {
|
||||
GETCHAR(opt, p);
|
||||
GETCHAR(olen, p);
|
||||
|
||||
if (olen < 2 || olen > len) {
|
||||
break;
|
||||
}
|
||||
|
||||
printer(arg, " <");
|
||||
len -= olen;
|
||||
|
||||
if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
|
||||
printer(arg, " %s", cbcp_optionnames[opt-1]);
|
||||
else
|
||||
printer(arg, " option=0x%x", opt);
|
||||
|
||||
if (olen > 2) {
|
||||
GETCHAR(delay, p);
|
||||
printer(arg, " delay = %d", delay);
|
||||
}
|
||||
|
||||
if (olen > 3) {
|
||||
int addrt;
|
||||
char str[256];
|
||||
|
||||
GETCHAR(addrt, p);
|
||||
memcpy(str, p, olen - 4);
|
||||
str[olen - 4] = 0;
|
||||
printer(arg, " number = %s", str);
|
||||
}
|
||||
printer(arg, ">");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (; len > 0; --len) {
|
||||
GETCHAR(code, p);
|
||||
printer(arg, " %.2x", code);
|
||||
}
|
||||
|
||||
return p - pstart;
|
||||
}
|
||||
|
||||
/* received CBCP request */
|
||||
static void
|
||||
cbcp_recvreq(us, pckt, pcktlen)
|
||||
cbcp_state *us;
|
||||
char *pckt;
|
||||
int pcktlen;
|
||||
{
|
||||
u_char type, opt_len, delay, addr_type;
|
||||
char address[256];
|
||||
int len = pcktlen;
|
||||
|
||||
address[0] = 0;
|
||||
|
||||
while (len) {
|
||||
syslog(LOG_DEBUG, "length: %d", len);
|
||||
|
||||
GETCHAR(type, pckt);
|
||||
GETCHAR(opt_len, pckt);
|
||||
|
||||
if (opt_len > 2)
|
||||
GETCHAR(delay, pckt);
|
||||
|
||||
us->us_allowed |= (1 << type);
|
||||
|
||||
switch(type) {
|
||||
case CB_CONF_NO:
|
||||
syslog(LOG_DEBUG, "no callback allowed");
|
||||
break;
|
||||
|
||||
case CB_CONF_USER:
|
||||
syslog(LOG_DEBUG, "user callback allowed");
|
||||
if (opt_len > 4) {
|
||||
GETCHAR(addr_type, pckt);
|
||||
memcpy(address, pckt, opt_len - 4);
|
||||
address[opt_len - 4] = 0;
|
||||
if (address[0])
|
||||
syslog(LOG_DEBUG, "address: %s", address);
|
||||
}
|
||||
break;
|
||||
|
||||
case CB_CONF_ADMIN:
|
||||
syslog(LOG_DEBUG, "user admin defined allowed");
|
||||
break;
|
||||
|
||||
case CB_CONF_LIST:
|
||||
break;
|
||||
}
|
||||
len -= opt_len;
|
||||
}
|
||||
|
||||
cbcp_resp(us);
|
||||
}
|
||||
|
||||
static void
|
||||
cbcp_resp(us)
|
||||
cbcp_state *us;
|
||||
{
|
||||
u_char cb_type;
|
||||
u_char buf[256];
|
||||
u_char *bufp = buf;
|
||||
int len = 0;
|
||||
|
||||
cb_type = us->us_allowed & us->us_type;
|
||||
syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type);
|
||||
|
||||
#if 0
|
||||
if (!cb_type)
|
||||
lcp_down(us->us_unit);
|
||||
#endif
|
||||
|
||||
if (cb_type & ( 1 << CB_CONF_USER ) ) {
|
||||
syslog(LOG_DEBUG, "cbcp_resp CONF_USER");
|
||||
PUTCHAR(CB_CONF_USER, bufp);
|
||||
len = 3 + 1 + strlen(us->us_number) + 1;
|
||||
PUTCHAR(len , bufp);
|
||||
PUTCHAR(5, bufp); /* delay */
|
||||
PUTCHAR(1, bufp);
|
||||
BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
|
||||
cbcp_send(us, CBCP_RESP, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
|
||||
syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN");
|
||||
PUTCHAR(CB_CONF_ADMIN, bufp);
|
||||
len = 3 + 1;
|
||||
PUTCHAR(len , bufp);
|
||||
PUTCHAR(5, bufp); /* delay */
|
||||
PUTCHAR(0, bufp);
|
||||
cbcp_send(us, CBCP_RESP, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cb_type & ( 1 << CB_CONF_NO ) ) {
|
||||
syslog(LOG_DEBUG, "cbcp_resp CONF_NO");
|
||||
PUTCHAR(CB_CONF_NO, bufp);
|
||||
len = 3;
|
||||
PUTCHAR(len , bufp);
|
||||
PUTCHAR(0, bufp);
|
||||
cbcp_send(us, CBCP_RESP, buf, len);
|
||||
(*ipcp_protent.open)(us->us_unit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cbcp_send(us, code, buf, len)
|
||||
cbcp_state *us;
|
||||
u_char code;
|
||||
u_char *buf;
|
||||
int len;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
outp = outpacket_buf;
|
||||
|
||||
outlen = 4 + len;
|
||||
|
||||
MAKEHEADER(outp, PPP_CBCP);
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(us->us_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
|
||||
if (len)
|
||||
BCOPY(buf, outp, len);
|
||||
|
||||
output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
}
|
||||
|
||||
static void
|
||||
cbcp_recvack(us, pckt, len)
|
||||
cbcp_state *us;
|
||||
char *pckt;
|
||||
int len;
|
||||
{
|
||||
u_char type, delay, addr_type;
|
||||
int opt_len;
|
||||
char address[256];
|
||||
|
||||
if (len) {
|
||||
GETCHAR(type, pckt);
|
||||
GETCHAR(opt_len, pckt);
|
||||
|
||||
if (opt_len > 2)
|
||||
GETCHAR(delay, pckt);
|
||||
|
||||
if (opt_len > 4) {
|
||||
GETCHAR(addr_type, pckt);
|
||||
memcpy(address, pckt, opt_len - 4);
|
||||
address[opt_len - 4] = 0;
|
||||
if (address[0])
|
||||
syslog(LOG_DEBUG, "peer will call: %s", address);
|
||||
}
|
||||
}
|
||||
|
||||
cbcp_up(us);
|
||||
}
|
||||
|
||||
extern int persist;
|
||||
|
||||
/* ok peer will do callback */
|
||||
static void
|
||||
cbcp_up(us)
|
||||
cbcp_state *us;
|
||||
{
|
||||
persist = 0;
|
||||
lcp_close(0, "Call me back, please");
|
||||
}
|
||||
26
c/src/libnetworking/pppd/cbcp.h
Normal file
26
c/src/libnetworking/pppd/cbcp.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef CBCP_H
|
||||
#define CBCP_H
|
||||
|
||||
typedef struct cbcp_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
u_char us_id; /* Current id */
|
||||
u_char us_allowed;
|
||||
int us_type;
|
||||
char *us_number; /* Telefone Number */
|
||||
} cbcp_state;
|
||||
|
||||
extern cbcp_state cbcp[];
|
||||
|
||||
extern struct protent cbcp_protent;
|
||||
|
||||
#define CBCP_MINLEN 4
|
||||
|
||||
#define CBCP_REQ 1
|
||||
#define CBCP_RESP 2
|
||||
#define CBCP_ACK 3
|
||||
|
||||
#define CB_CONF_NO 1
|
||||
#define CB_CONF_USER 2
|
||||
#define CB_CONF_ADMIN 3
|
||||
#define CB_CONF_LIST 4
|
||||
#endif
|
||||
1117
c/src/libnetworking/pppd/ccp.c
Normal file
1117
c/src/libnetworking/pppd/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
48
c/src/libnetworking/pppd/ccp.h
Normal file
48
c/src/libnetworking/pppd/ccp.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* ccp.h - Definitions for PPP Compression Control Protocol.
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
typedef struct ccp_options {
|
||||
u_int bsd_compress: 1; /* do BSD Compress? */
|
||||
u_int deflate: 1; /* do Deflate? */
|
||||
u_int predictor_1: 1; /* do Predictor-1? */
|
||||
u_int predictor_2: 1; /* do Predictor-2? */
|
||||
u_int deflate_correct: 1; /* use correct code for deflate? */
|
||||
u_int deflate_draft: 1; /* use draft RFC code for deflate? */
|
||||
u_short bsd_bits; /* # bits/code for BSD Compress */
|
||||
u_short deflate_size; /* lg(window size) for Deflate */
|
||||
short method; /* code for chosen compression method */
|
||||
} ccp_options;
|
||||
|
||||
extern fsm ccp_fsm[];
|
||||
extern ccp_options ccp_wantoptions[];
|
||||
extern ccp_options ccp_gotoptions[];
|
||||
extern ccp_options ccp_allowoptions[];
|
||||
extern ccp_options ccp_hisoptions[];
|
||||
|
||||
extern struct protent ccp_protent;
|
||||
872
c/src/libnetworking/pppd/chap.c
Normal file
872
c/src/libnetworking/pppd/chap.c
Normal file
@@ -0,0 +1,872 @@
|
||||
/*
|
||||
* chap.c - Challenge Handshake Authentication Protocol.
|
||||
*
|
||||
* Copyright (c) 1993 The Australian National University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Australian National University. The name of the University
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 1991 Gregory M. Christy.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Gregory M. Christy. The name of the author 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
#include "md5.h"
|
||||
#ifdef CHAPMS
|
||||
#include "chap_ms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
static void ChapInit __P((int));
|
||||
static void ChapLowerUp __P((int));
|
||||
static void ChapLowerDown __P((int));
|
||||
static void ChapInput __P((int, u_char *, int));
|
||||
static void ChapProtocolReject __P((int));
|
||||
static int ChapPrintPkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
||||
struct protent chap_protent = {
|
||||
PPP_CHAP,
|
||||
ChapInit,
|
||||
ChapInput,
|
||||
ChapProtocolReject,
|
||||
ChapLowerUp,
|
||||
ChapLowerDown,
|
||||
NULL,
|
||||
NULL,
|
||||
ChapPrintPkt,
|
||||
NULL,
|
||||
1,
|
||||
"CHAP",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
||||
|
||||
static void ChapChallengeTimeout __P((void *));
|
||||
static void ChapResponseTimeout __P((void *));
|
||||
static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int));
|
||||
static void ChapRechallenge __P((void *));
|
||||
static void ChapReceiveResponse __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveSuccess __P((chap_state *, u_char *, int, int));
|
||||
static void ChapReceiveFailure __P((chap_state *, u_char *, int, int));
|
||||
static void ChapSendStatus __P((chap_state *, int));
|
||||
static void ChapSendChallenge __P((chap_state *));
|
||||
static void ChapSendResponse __P((chap_state *));
|
||||
static void ChapGenChallenge __P((chap_state *));
|
||||
/* #include <stdlib.h> */
|
||||
|
||||
extern double drand48 __P((void));
|
||||
/*{
|
||||
return (((double)rand())/RAND_MAX);
|
||||
}
|
||||
*/
|
||||
extern void srand48 __P((long));
|
||||
|
||||
/*
|
||||
* ChapInit - Initialize a CHAP unit.
|
||||
*/
|
||||
static void
|
||||
ChapInit(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
BZERO(cstate, sizeof(*cstate));
|
||||
cstate->unit = unit;
|
||||
cstate->clientstate = CHAPCS_INITIAL;
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
cstate->timeouttime = CHAP_DEFTIMEOUT;
|
||||
cstate->max_transmits = CHAP_DEFTRANSMITS;
|
||||
/* random number generator is initialized in magic_init */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapAuthWithPeer - Authenticate us with our peer (start client).
|
||||
*
|
||||
*/
|
||||
void
|
||||
ChapAuthWithPeer(unit, our_name, digest)
|
||||
int unit;
|
||||
char *our_name;
|
||||
int digest;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
cstate->resp_name = our_name;
|
||||
cstate->resp_type = digest;
|
||||
|
||||
if (cstate->clientstate == CHAPCS_INITIAL ||
|
||||
cstate->clientstate == CHAPCS_PENDING) {
|
||||
/* lower layer isn't up - wait until later */
|
||||
cstate->clientstate = CHAPCS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We get here as a result of LCP coming up.
|
||||
* So even if CHAP was open before, we will
|
||||
* have to re-authenticate ourselves.
|
||||
*/
|
||||
cstate->clientstate = CHAPCS_LISTEN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapAuthPeer - Authenticate our peer (start server).
|
||||
*/
|
||||
void
|
||||
ChapAuthPeer(unit, our_name, digest)
|
||||
int unit;
|
||||
char *our_name;
|
||||
int digest;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
cstate->chal_name = our_name;
|
||||
cstate->chal_type = digest;
|
||||
|
||||
if (cstate->serverstate == CHAPSS_INITIAL ||
|
||||
cstate->serverstate == CHAPSS_PENDING) {
|
||||
/* lower layer isn't up - wait until later */
|
||||
cstate->serverstate = CHAPSS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate); /* crank it up dude! */
|
||||
cstate->serverstate = CHAPSS_INITIAL_CHAL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapChallengeTimeout - Timeout expired on sending challenge.
|
||||
*/
|
||||
static void
|
||||
ChapChallengeTimeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
chap_state *cstate = (chap_state *) arg;
|
||||
|
||||
/* if we aren't sending challenges, don't worry. then again we */
|
||||
/* probably shouldn't be here either */
|
||||
if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
|
||||
cstate->serverstate != CHAPSS_RECHALLENGE)
|
||||
return;
|
||||
|
||||
if (cstate->chal_transmits >= cstate->max_transmits) {
|
||||
/* give up on peer */
|
||||
syslog(LOG_ERR, "Peer failed to respond to CHAP challenge");
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
return;
|
||||
}
|
||||
|
||||
ChapSendChallenge(cstate); /* Re-send challenge */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapResponseTimeout - Timeout expired on sending response.
|
||||
*/
|
||||
static void
|
||||
ChapResponseTimeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
chap_state *cstate = (chap_state *) arg;
|
||||
|
||||
/* if we aren't sending a response, don't worry. */
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE)
|
||||
return;
|
||||
|
||||
ChapSendResponse(cstate); /* re-send response */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapRechallenge - Time to challenge the peer again.
|
||||
*/
|
||||
static void
|
||||
ChapRechallenge(arg)
|
||||
void *arg;
|
||||
{
|
||||
chap_state *cstate = (chap_state *) arg;
|
||||
|
||||
/* if we aren't sending a response, don't worry. */
|
||||
if (cstate->serverstate != CHAPSS_OPEN)
|
||||
return;
|
||||
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate);
|
||||
cstate->serverstate = CHAPSS_RECHALLENGE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapLowerUp - The lower layer is up.
|
||||
*
|
||||
* Start up if we have pending requests.
|
||||
*/
|
||||
static void
|
||||
ChapLowerUp(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
if (cstate->clientstate == CHAPCS_INITIAL)
|
||||
cstate->clientstate = CHAPCS_CLOSED;
|
||||
else if (cstate->clientstate == CHAPCS_PENDING)
|
||||
cstate->clientstate = CHAPCS_LISTEN;
|
||||
|
||||
if (cstate->serverstate == CHAPSS_INITIAL)
|
||||
cstate->serverstate = CHAPSS_CLOSED;
|
||||
else if (cstate->serverstate == CHAPSS_PENDING) {
|
||||
ChapGenChallenge(cstate);
|
||||
ChapSendChallenge(cstate);
|
||||
cstate->serverstate = CHAPSS_INITIAL_CHAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapLowerDown - The lower layer is down.
|
||||
*
|
||||
* Cancel all timeouts.
|
||||
*/
|
||||
static void
|
||||
ChapLowerDown(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
/* Timeout(s) pending? Cancel if so. */
|
||||
if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
|
||||
cstate->serverstate == CHAPSS_RECHALLENGE)
|
||||
UNTIMEOUT(ChapChallengeTimeout, cstate);
|
||||
else if (cstate->serverstate == CHAPSS_OPEN
|
||||
&& cstate->chal_interval != 0)
|
||||
UNTIMEOUT(ChapRechallenge, cstate);
|
||||
if (cstate->clientstate == CHAPCS_RESPONSE)
|
||||
UNTIMEOUT(ChapResponseTimeout, cstate);
|
||||
|
||||
cstate->clientstate = CHAPCS_INITIAL;
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapProtocolReject - Peer doesn't grok CHAP.
|
||||
*/
|
||||
static void
|
||||
ChapProtocolReject(unit)
|
||||
int unit;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
if (cstate->serverstate != CHAPSS_INITIAL &&
|
||||
cstate->serverstate != CHAPSS_CLOSED)
|
||||
auth_peer_fail(unit, PPP_CHAP);
|
||||
if (cstate->clientstate != CHAPCS_INITIAL &&
|
||||
cstate->clientstate != CHAPCS_CLOSED)
|
||||
auth_withpeer_fail(unit, PPP_CHAP);
|
||||
ChapLowerDown(unit); /* shutdown chap */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapInput - Input CHAP packet.
|
||||
*/
|
||||
static void
|
||||
ChapInput(unit, inpacket, packet_len)
|
||||
int unit;
|
||||
u_char *inpacket;
|
||||
int packet_len;
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Parse header (code, id and length).
|
||||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (packet_len < CHAP_HEADERLEN) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < CHAP_HEADERLEN) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length."));
|
||||
return;
|
||||
}
|
||||
if (len > packet_len) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
len -= CHAP_HEADERLEN;
|
||||
|
||||
/*
|
||||
* Action depends on code (as in fact it usually does :-).
|
||||
*/
|
||||
switch (code) {
|
||||
case CHAP_CHALLENGE:
|
||||
ChapReceiveChallenge(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
case CHAP_RESPONSE:
|
||||
ChapReceiveResponse(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
case CHAP_FAILURE:
|
||||
ChapReceiveFailure(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
case CHAP_SUCCESS:
|
||||
ChapReceiveSuccess(cstate, inp, id, len);
|
||||
break;
|
||||
|
||||
default: /* Need code reject? */
|
||||
syslog(LOG_WARNING, "Unknown CHAP code (%d) received.", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapReceiveChallenge - Receive Challenge and send Response.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveChallenge(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
int rchallenge_len;
|
||||
u_char *rchallenge;
|
||||
int secret_len;
|
||||
char secret[MAXSECRETLEN];
|
||||
char rhostname[256];
|
||||
MD5_CTX mdContext;
|
||||
u_char hash[MD5_SIGNATURE_SIZE];
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.", id));
|
||||
if (cstate->clientstate == CHAPCS_CLOSED ||
|
||||
cstate->clientstate == CHAPCS_PENDING) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < 2) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
|
||||
GETCHAR(rchallenge_len, inp);
|
||||
len -= sizeof (u_char) + rchallenge_len; /* now name field length */
|
||||
if (len < 0) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
rchallenge = inp;
|
||||
INCPTR(rchallenge_len, inp);
|
||||
|
||||
if (len >= sizeof(rhostname))
|
||||
len = sizeof(rhostname) - 1;
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'",
|
||||
rhostname));
|
||||
|
||||
/* Microsoft doesn't send their name back in the PPP packet */
|
||||
if (remote_name[0] != 0 && (explicit_remote || rhostname[0] == 0)) {
|
||||
strncpy(rhostname, remote_name, sizeof(rhostname));
|
||||
rhostname[sizeof(rhostname) - 1] = 0;
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name",
|
||||
rhostname));
|
||||
}
|
||||
|
||||
/* get secret for authenticating ourselves with the specified host */
|
||||
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
|
||||
secret, &secret_len, 0)) {
|
||||
secret_len = 0; /* assume null secret if can't find one */
|
||||
syslog(LOG_WARNING, "No CHAP secret found for authenticating us to %s",
|
||||
rhostname);
|
||||
}
|
||||
|
||||
/* cancel response send timeout if necessary */
|
||||
if (cstate->clientstate == CHAPCS_RESPONSE)
|
||||
UNTIMEOUT(ChapResponseTimeout, cstate);
|
||||
|
||||
cstate->resp_id = id;
|
||||
cstate->resp_transmits = 0;
|
||||
|
||||
/* generate MD based on negotiated type */
|
||||
switch (cstate->resp_type) {
|
||||
|
||||
case CHAP_DIGEST_MD5:
|
||||
MD5Init(&mdContext);
|
||||
MD5Update(&mdContext, &cstate->resp_id, 1);
|
||||
MD5Update(&mdContext, secret, secret_len);
|
||||
MD5Update(&mdContext, rchallenge, rchallenge_len);
|
||||
MD5Final(hash, &mdContext);
|
||||
BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
|
||||
cstate->resp_length = MD5_SIGNATURE_SIZE;
|
||||
break;
|
||||
|
||||
#ifdef CHAPMS
|
||||
case CHAP_MICROSOFT:
|
||||
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->resp_type));
|
||||
return;
|
||||
}
|
||||
|
||||
BZERO(secret, sizeof(secret));
|
||||
ChapSendResponse(cstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapReceiveResponse - Receive and process response.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveResponse(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char *remmd, remmd_len;
|
||||
int secret_len, old_state;
|
||||
int code;
|
||||
char rhostname[256];
|
||||
MD5_CTX mdContext;
|
||||
char secret[MAXSECRETLEN];
|
||||
u_char hash[MD5_SIGNATURE_SIZE];
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.", id));
|
||||
|
||||
if (cstate->serverstate == CHAPSS_CLOSED ||
|
||||
cstate->serverstate == CHAPSS_PENDING) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d",
|
||||
cstate->serverstate));
|
||||
return;
|
||||
}
|
||||
|
||||
if (id != cstate->chal_id)
|
||||
return; /* doesn't match ID of last challenge */
|
||||
|
||||
/*
|
||||
* If we have received a duplicate or bogus Response,
|
||||
* we have to send the same answer (Success/Failure)
|
||||
* as we did for the first Response we saw.
|
||||
*/
|
||||
if (cstate->serverstate == CHAPSS_OPEN) {
|
||||
ChapSendStatus(cstate, CHAP_SUCCESS);
|
||||
return;
|
||||
}
|
||||
if (cstate->serverstate == CHAPSS_BADAUTH) {
|
||||
ChapSendStatus(cstate, CHAP_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < 2) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(remmd_len, inp); /* get length of MD */
|
||||
remmd = inp; /* get pointer to MD */
|
||||
INCPTR(remmd_len, inp);
|
||||
|
||||
len -= sizeof (u_char) + remmd_len;
|
||||
if (len < 0) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapChallengeTimeout, cstate);
|
||||
|
||||
if (len >= sizeof(rhostname))
|
||||
len = sizeof(rhostname) - 1;
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s",
|
||||
rhostname));
|
||||
|
||||
/*
|
||||
* Get secret for authenticating them with us,
|
||||
* do the hash ourselves, and compare the result.
|
||||
*/
|
||||
code = CHAP_FAILURE;
|
||||
if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
|
||||
secret, &secret_len, 1)) {
|
||||
syslog(LOG_WARNING, "No CHAP secret found for authenticating %s",
|
||||
rhostname);
|
||||
} else {
|
||||
|
||||
/* generate MD based on negotiated type */
|
||||
switch (cstate->chal_type) {
|
||||
|
||||
case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
|
||||
if (remmd_len != MD5_SIGNATURE_SIZE)
|
||||
break; /* it's not even the right length */
|
||||
MD5Init(&mdContext);
|
||||
MD5Update(&mdContext, &cstate->chal_id, 1);
|
||||
MD5Update(&mdContext, secret, secret_len);
|
||||
MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
|
||||
MD5Final(hash, &mdContext);
|
||||
|
||||
/* compare local and remote MDs and send the appropriate status */
|
||||
if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)
|
||||
code = CHAP_SUCCESS; /* they are the same! */
|
||||
break;
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d", cstate->chal_type));
|
||||
}
|
||||
}
|
||||
|
||||
BZERO(secret, sizeof(secret));
|
||||
ChapSendStatus(cstate, code);
|
||||
|
||||
if (code == CHAP_SUCCESS) {
|
||||
old_state = cstate->serverstate;
|
||||
cstate->serverstate = CHAPSS_OPEN;
|
||||
if (old_state == CHAPSS_INITIAL_CHAL) {
|
||||
auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
|
||||
}
|
||||
if (cstate->chal_interval != 0)
|
||||
TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
|
||||
syslog(LOG_NOTICE, "CHAP peer authentication succeeded for %s",
|
||||
rhostname);
|
||||
|
||||
} else {
|
||||
syslog(LOG_ERR, "CHAP peer authentication failed for remote host %s",
|
||||
rhostname);
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapReceiveSuccess - Receive Success
|
||||
*/
|
||||
static void
|
||||
ChapReceiveSuccess(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
u_char id;
|
||||
int len;
|
||||
{
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.", id));
|
||||
|
||||
if (cstate->clientstate == CHAPCS_OPEN)
|
||||
/* presumably an answer to a duplicate response */
|
||||
return;
|
||||
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
||||
/* don't know what this is */
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapResponseTimeout, cstate);
|
||||
|
||||
/*
|
||||
* Print message.
|
||||
*/
|
||||
if (len > 0)
|
||||
PRINTMSG(inp, len);
|
||||
|
||||
cstate->clientstate = CHAPCS_OPEN;
|
||||
|
||||
auth_withpeer_success(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapReceiveFailure - Receive failure.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveFailure(cstate, inp, id, len)
|
||||
chap_state *cstate;
|
||||
u_char *inp;
|
||||
u_char id;
|
||||
int len;
|
||||
{
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.", id));
|
||||
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
||||
/* don't know what this is */
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapResponseTimeout, cstate);
|
||||
|
||||
/*
|
||||
* Print message.
|
||||
*/
|
||||
if (len > 0)
|
||||
PRINTMSG(inp, len);
|
||||
|
||||
syslog(LOG_ERR, "CHAP authentication failed");
|
||||
auth_withpeer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapSendChallenge - Send an Authenticate challenge.
|
||||
*/
|
||||
static void
|
||||
ChapSendChallenge(cstate)
|
||||
chap_state *cstate;
|
||||
{
|
||||
u_char *outp;
|
||||
int chal_len, name_len;
|
||||
int outlen;
|
||||
|
||||
chal_len = cstate->chal_len;
|
||||
name_len = strlen(cstate->chal_name);
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
|
||||
|
||||
PUTCHAR(CHAP_CHALLENGE, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
|
||||
PUTCHAR(chal_len, outp); /* put length of challenge */
|
||||
BCOPY(cstate->challenge, outp, chal_len);
|
||||
INCPTR(chal_len, outp);
|
||||
|
||||
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
|
||||
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.", cstate->chal_id));
|
||||
|
||||
TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
|
||||
++cstate->chal_transmits;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapSendStatus - Send a status response (ack or nak).
|
||||
*/
|
||||
static void
|
||||
ChapSendStatus(cstate, code)
|
||||
chap_state *cstate;
|
||||
int code;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen, msglen;
|
||||
char msg[256];
|
||||
|
||||
if (code == CHAP_SUCCESS)
|
||||
sprintf(msg, "Welcome to %s.", hostname);
|
||||
else
|
||||
sprintf(msg, "I don't like you. Go 'way.");
|
||||
msglen = strlen(msg);
|
||||
|
||||
outlen = CHAP_HEADERLEN + msglen;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.", code,
|
||||
cstate->chal_id));
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapGenChallenge is used to generate a pseudo-random challenge string of
|
||||
* a pseudo-random length between min_len and max_len. The challenge
|
||||
* string and its length are stored in *cstate, and various other fields of
|
||||
* *cstate are initialized.
|
||||
*/
|
||||
|
||||
static void
|
||||
ChapGenChallenge(cstate)
|
||||
chap_state *cstate;
|
||||
{
|
||||
int chal_len;
|
||||
u_char *ptr = cstate->challenge;
|
||||
unsigned int i;
|
||||
|
||||
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
|
||||
MAX_CHALLENGE_LENGTH */
|
||||
chal_len = (unsigned) ((drand48() *
|
||||
(MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
|
||||
MIN_CHALLENGE_LENGTH);
|
||||
cstate->chal_len = chal_len;
|
||||
cstate->chal_id = ++cstate->id;
|
||||
cstate->chal_transmits = 0;
|
||||
|
||||
/* generate a random string */
|
||||
for (i = 0; i < chal_len; i++ )
|
||||
*ptr++ = (char) (drand48() * 0xff);
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapSendResponse - send a response packet with values as specified
|
||||
* in *cstate.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ChapSendResponse(cstate)
|
||||
chap_state *cstate;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen, md_len, name_len;
|
||||
|
||||
md_len = cstate->resp_length;
|
||||
name_len = strlen(cstate->resp_name);
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP);
|
||||
|
||||
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
|
||||
PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
|
||||
PUTSHORT(outlen, outp); /* packet length */
|
||||
|
||||
PUTCHAR(md_len, outp); /* length of MD */
|
||||
BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */
|
||||
INCPTR(md_len, outp);
|
||||
|
||||
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
|
||||
|
||||
/* send the packet */
|
||||
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
cstate->clientstate = CHAPCS_RESPONSE;
|
||||
TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
|
||||
++cstate->resp_transmits;
|
||||
}
|
||||
|
||||
/*
|
||||
* ChapPrintPkt - print the contents of a CHAP packet.
|
||||
*/
|
||||
static char *ChapCodenames[] = {
|
||||
"Challenge", "Response", "Success", "Failure"
|
||||
};
|
||||
|
||||
static int
|
||||
ChapPrintPkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len;
|
||||
int clen, nlen;
|
||||
u_char x;
|
||||
if (plen < CHAP_HEADERLEN)
|
||||
return 0;
|
||||
GETCHAR(code, p);
|
||||
GETCHAR(id, p);
|
||||
GETSHORT(len, p);
|
||||
if (len < CHAP_HEADERLEN || len > plen)
|
||||
return 0;
|
||||
|
||||
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
|
||||
printer(arg, " %s", ChapCodenames[code-1]);
|
||||
else
|
||||
printer(arg, " code=0x%x", code);
|
||||
printer(arg, " id=0x%x", id);
|
||||
len -= CHAP_HEADERLEN;
|
||||
switch (code) {
|
||||
case CHAP_CHALLENGE:
|
||||
case CHAP_RESPONSE:
|
||||
if (len < 1)
|
||||
break;
|
||||
clen = p[0];
|
||||
if (len < clen + 1)
|
||||
break;
|
||||
++p;
|
||||
nlen = len - clen - 1;
|
||||
printer(arg, " <");
|
||||
for (; clen > 0; --clen) {
|
||||
GETCHAR(x, p);
|
||||
printer(arg, "%.2x", x);
|
||||
}
|
||||
printer(arg, ">, name = ");
|
||||
print_string((char *)p, nlen, printer, arg);
|
||||
break;
|
||||
case CHAP_FAILURE:
|
||||
case CHAP_SUCCESS:
|
||||
printer(arg, " ");
|
||||
print_string((char *)p, len, printer, arg);
|
||||
break;
|
||||
default:
|
||||
for (clen = len; clen > 0; --clen) {
|
||||
GETCHAR(x, p);
|
||||
printer(arg, " %.2x", x);
|
||||
}
|
||||
}
|
||||
return len + CHAP_HEADERLEN;
|
||||
}
|
||||
124
c/src/libnetworking/pppd/chap.h
Normal file
124
c/src/libnetworking/pppd/chap.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* chap.h - Challenge Handshake Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1993 The Australian National University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Australian National University. The name of the University
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 1991 Gregory M. Christy
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 author.
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef __CHAP_INCLUDE__
|
||||
|
||||
/* Code + ID + length */
|
||||
#define CHAP_HEADERLEN 4
|
||||
|
||||
/*
|
||||
* CHAP codes.
|
||||
*/
|
||||
|
||||
#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */
|
||||
#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */
|
||||
#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */
|
||||
#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */
|
||||
|
||||
#define CHAP_CHALLENGE 1
|
||||
#define CHAP_RESPONSE 2
|
||||
#define CHAP_SUCCESS 3
|
||||
#define CHAP_FAILURE 4
|
||||
|
||||
/*
|
||||
* Challenge lengths (for challenges we send) and other limits.
|
||||
*/
|
||||
#define MIN_CHALLENGE_LENGTH 32
|
||||
#define MAX_CHALLENGE_LENGTH 64
|
||||
#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */
|
||||
|
||||
/*
|
||||
* Each interface is described by a chap structure.
|
||||
*/
|
||||
|
||||
typedef struct chap_state {
|
||||
int unit; /* Interface unit number */
|
||||
int clientstate; /* Client state */
|
||||
int serverstate; /* Server state */
|
||||
u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */
|
||||
u_char chal_len; /* challenge length */
|
||||
u_char chal_id; /* ID of last challenge */
|
||||
u_char chal_type; /* hash algorithm for challenges */
|
||||
u_char id; /* Current id */
|
||||
char *chal_name; /* Our name to use with challenge */
|
||||
int chal_interval; /* Time until we challenge peer again */
|
||||
int timeouttime; /* Timeout time in seconds */
|
||||
int max_transmits; /* Maximum # of challenge transmissions */
|
||||
int chal_transmits; /* Number of transmissions of challenge */
|
||||
int resp_transmits; /* Number of transmissions of response */
|
||||
u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */
|
||||
u_char resp_length; /* length of response */
|
||||
u_char resp_id; /* ID for response messages */
|
||||
u_char resp_type; /* hash algorithm for responses */
|
||||
char *resp_name; /* Our name to send with response */
|
||||
} chap_state;
|
||||
|
||||
|
||||
/*
|
||||
* Client (peer) states.
|
||||
*/
|
||||
#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */
|
||||
#define CHAPCS_LISTEN 3 /* Listening for a challenge */
|
||||
#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */
|
||||
#define CHAPCS_OPEN 5 /* We've received Success */
|
||||
|
||||
/*
|
||||
* Server (authenticator) states.
|
||||
*/
|
||||
#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPSS_PENDING 2 /* Auth peer when lower up */
|
||||
#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */
|
||||
#define CHAPSS_OPEN 4 /* We've sent a Success msg */
|
||||
#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */
|
||||
#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define CHAP_DEFTIMEOUT 3 /* Timeout time in seconds */
|
||||
#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */
|
||||
|
||||
extern chap_state chap[];
|
||||
|
||||
void ChapAuthWithPeer __P((int, char *, int));
|
||||
void ChapAuthPeer __P((int, char *, int));
|
||||
|
||||
extern struct protent chap_protent;
|
||||
|
||||
#define __CHAP_INCLUDE__
|
||||
#endif /* __CHAP_INCLUDE__ */
|
||||
335
c/src/libnetworking/pppd/chap_ms.c
Normal file
335
c/src/libnetworking/pppd/chap_ms.c
Normal file
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* chap_ms.c - Microsoft MS-CHAP compatible implementation.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
* http://www.strataware.com/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Eric Rosenquist. The name of the author 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
|
||||
*
|
||||
* Implemented LANManager type password response to MS-CHAP challenges.
|
||||
* Now pppd provides both NT style and LANMan style blocks, and the
|
||||
* prefered is set by option "ms-lanman". Default is to use NT.
|
||||
* The hash text (StdText) was taken from Win95 RASAPI32.DLL.
|
||||
*
|
||||
* You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
#ifdef CHAPMS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
#include "chap_ms.h"
|
||||
#include "md4.h"
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
#include <des.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
u_char LANManResp[24];
|
||||
u_char NTResp[24];
|
||||
u_char UseNT; /* If 1, ignore the LANMan response field */
|
||||
} MS_ChapResponse;
|
||||
/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
|
||||
in case this struct gets padded. */
|
||||
|
||||
|
||||
static void ChallengeResponse __P((u_char *, u_char *, u_char *));
|
||||
static void DesEncrypt __P((u_char *, u_char *, u_char *));
|
||||
static void MakeKey __P((u_char *, u_char *));
|
||||
static u_char Get7Bits __P((u_char *, int));
|
||||
static void ChapMS_NT __P((char *, int, char *, int, MS_ChapResponse *));
|
||||
#ifdef MSLANMAN
|
||||
static void ChapMS_LANMan __P((char *, int, char *, int, MS_ChapResponse *));
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
static void Expand __P((u_char *, u_char *));
|
||||
static void Collapse __P((u_char *, u_char *));
|
||||
#endif
|
||||
|
||||
static void
|
||||
ChallengeResponse(challenge, pwHash, response)
|
||||
u_char *challenge; /* IN 8 octets */
|
||||
u_char *pwHash; /* IN 16 octets */
|
||||
u_char *response; /* OUT 24 octets */
|
||||
{
|
||||
char ZPasswordHash[21];
|
||||
|
||||
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||
BCOPY(pwHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
|
||||
|
||||
#if 0
|
||||
log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG);
|
||||
#endif
|
||||
|
||||
DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
|
||||
DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
|
||||
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
|
||||
|
||||
#if 0
|
||||
log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
static void
|
||||
DesEncrypt(clear, key, cipher)
|
||||
u_char *clear; /* IN 8 octets */
|
||||
u_char *key; /* IN 7 octets */
|
||||
u_char *cipher; /* OUT 8 octets */
|
||||
{
|
||||
u_char des_key[8];
|
||||
u_char crypt_key[66];
|
||||
u_char des_input[66];
|
||||
|
||||
MakeKey(key, des_key);
|
||||
|
||||
Expand(des_key, crypt_key);
|
||||
setkey(crypt_key);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
|
||||
#endif
|
||||
|
||||
Expand(clear, des_input);
|
||||
encrypt(des_input, 0);
|
||||
Collapse(des_input, cipher);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* USE_CRYPT */
|
||||
|
||||
static void
|
||||
DesEncrypt(clear, key, cipher)
|
||||
u_char *clear; /* IN 8 octets */
|
||||
u_char *key; /* IN 7 octets */
|
||||
u_char *cipher; /* OUT 8 octets */
|
||||
{
|
||||
des_cblock des_key;
|
||||
des_key_schedule key_schedule;
|
||||
|
||||
MakeKey(key, des_key);
|
||||
|
||||
des_set_key(&des_key, key_schedule);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
|
||||
#endif
|
||||
|
||||
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_CRYPT */
|
||||
|
||||
|
||||
static u_char Get7Bits(input, startBit)
|
||||
u_char *input;
|
||||
int startBit;
|
||||
{
|
||||
register unsigned int word;
|
||||
|
||||
word = (unsigned)input[startBit / 8] << 8;
|
||||
word |= (unsigned)input[startBit / 8 + 1];
|
||||
|
||||
word >>= 15 - (startBit % 8 + 7);
|
||||
|
||||
return word & 0xFE;
|
||||
}
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
|
||||
/* in == 8-byte string (expanded version of the 56-bit key)
|
||||
* out == 64-byte string where each byte is either 1 or 0
|
||||
* Note that the low-order "bit" is always ignored by by setkey()
|
||||
*/
|
||||
static void Expand(in, out)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
{
|
||||
int j, c;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 64; in++){
|
||||
c = *in;
|
||||
for(j = 7; j >= 0; j--)
|
||||
*out++ = (c >> j) & 01;
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* The inverse of Expand
|
||||
*/
|
||||
static void Collapse(in, out)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
{
|
||||
int j;
|
||||
int i;
|
||||
unsigned int c;
|
||||
|
||||
for (i = 0; i < 64; i += 8, out++) {
|
||||
c = 0;
|
||||
for (j = 7; j >= 0; j--, in++)
|
||||
c |= *in << j;
|
||||
*out = c & 0xff;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void MakeKey(key, des_key)
|
||||
u_char *key; /* IN 56 bit DES key missing parity bits */
|
||||
u_char *des_key; /* OUT 64 bit DES key with parity bits added */
|
||||
{
|
||||
des_key[0] = Get7Bits(key, 0);
|
||||
des_key[1] = Get7Bits(key, 7);
|
||||
des_key[2] = Get7Bits(key, 14);
|
||||
des_key[3] = Get7Bits(key, 21);
|
||||
des_key[4] = Get7Bits(key, 28);
|
||||
des_key[5] = Get7Bits(key, 35);
|
||||
des_key[6] = Get7Bits(key, 42);
|
||||
des_key[7] = Get7Bits(key, 49);
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
des_set_odd_parity((des_cblock *)des_key);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X",
|
||||
key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response)
|
||||
char *rchallenge;
|
||||
int rchallenge_len;
|
||||
char *secret;
|
||||
int secret_len;
|
||||
MS_ChapResponse *response;
|
||||
{
|
||||
int i;
|
||||
MD4_CTX md4Context;
|
||||
u_char hash[MD4_SIGNATURE_SIZE];
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
|
||||
/* Initialize the Unicode version of the secret (== password). */
|
||||
/* This implicitly supports 8-bit ISO8859/1 characters. */
|
||||
BZERO(unicodePassword, sizeof(unicodePassword));
|
||||
for (i = 0; i < secret_len; i++)
|
||||
unicodePassword[i * 2] = (u_char)secret[i];
|
||||
|
||||
MD4Init(&md4Context);
|
||||
MD4Update(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */
|
||||
|
||||
MD4Final(hash, &md4Context); /* Tell MD4 we're done */
|
||||
|
||||
ChallengeResponse(rchallenge, hash, response->NTResp);
|
||||
}
|
||||
|
||||
#ifdef MSLANMAN
|
||||
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
|
||||
|
||||
static void
|
||||
ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, response)
|
||||
char *rchallenge;
|
||||
int rchallenge_len;
|
||||
char *secret;
|
||||
int secret_len;
|
||||
MS_ChapResponse *response;
|
||||
{
|
||||
int i;
|
||||
u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
|
||||
/* LANMan password is case insensitive */
|
||||
BZERO(UcasePassword, sizeof(UcasePassword));
|
||||
for (i = 0; i < secret_len; i++)
|
||||
UcasePassword[i] = (u_char)toupper(secret[i]);
|
||||
DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
|
||||
DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
|
||||
ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len)
|
||||
chap_state *cstate;
|
||||
char *rchallenge;
|
||||
int rchallenge_len;
|
||||
char *secret;
|
||||
int secret_len;
|
||||
{
|
||||
MS_ChapResponse response;
|
||||
#ifdef MSLANMAN
|
||||
extern int ms_lanman;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret));
|
||||
#endif
|
||||
BZERO(&response, sizeof(response));
|
||||
|
||||
/* Calculate both always */
|
||||
ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
|
||||
|
||||
#ifdef MSLANMAN
|
||||
ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
|
||||
|
||||
/* prefered method is set by option */
|
||||
response.UseNT = !ms_lanman;
|
||||
#else
|
||||
response.UseNT = 1;
|
||||
#endif
|
||||
|
||||
BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
|
||||
cstate->resp_length = MS_CHAP_RESPONSE_LEN;
|
||||
}
|
||||
|
||||
#endif /* CHAPMS */
|
||||
33
c/src/libnetworking/pppd/chap_ms.h
Normal file
33
c/src/libnetworking/pppd/chap_ms.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* chap.h - Challenge Handshake Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
* http://www.strataware.com/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Eric Rosenquist. The name of the author 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$
|
||||
*/
|
||||
|
||||
#ifndef __CHAPMS_INCLUDE__
|
||||
|
||||
#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */
|
||||
#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
|
||||
|
||||
void ChapMS __P((chap_state *, char *, int, char *, int));
|
||||
|
||||
#define __CHAPMS_INCLUDE__
|
||||
#endif /* __CHAPMS_INCLUDE__ */
|
||||
1004
c/src/libnetworking/pppd/chat.c
Normal file
1004
c/src/libnetworking/pppd/chat.c
Normal file
File diff suppressed because it is too large
Load Diff
348
c/src/libnetworking/pppd/demand.c
Normal file
348
c/src/libnetworking/pppd/demand.c
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* demand.c - Support routines for demand-dialling.
|
||||
*
|
||||
* Copyright (c) 1993 The Australian National University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Australian National University. The name of the University
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef PPP_FILTER
|
||||
#include <net/if.h>
|
||||
#include <net/bpf.h>
|
||||
#include <pcap.h>
|
||||
#endif
|
||||
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
#include "ipcp.h"
|
||||
#include "lcp.h"
|
||||
|
||||
char *frame;
|
||||
int framelen;
|
||||
int framemax;
|
||||
int escape_flag;
|
||||
int flush_flag;
|
||||
int fcs;
|
||||
|
||||
struct packet {
|
||||
int length;
|
||||
struct packet *next;
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
struct packet *pend_q;
|
||||
struct packet *pend_qtail;
|
||||
|
||||
static int active_packet __P((unsigned char *, int));
|
||||
|
||||
/*
|
||||
* demand_conf - configure the interface for doing dial-on-demand.
|
||||
*/
|
||||
void
|
||||
demand_conf()
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
/* framemax = lcp_allowoptions[0].mru;
|
||||
if (framemax < PPP_MRU) */
|
||||
framemax = PPP_MRU;
|
||||
framemax += PPP_HDRLEN + PPP_FCSLEN;
|
||||
frame = malloc(framemax);
|
||||
if (frame == NULL)
|
||||
novm("demand frame");
|
||||
framelen = 0;
|
||||
pend_q = NULL;
|
||||
escape_flag = 0;
|
||||
flush_flag = 0;
|
||||
fcs = PPP_INITFCS;
|
||||
|
||||
ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
|
||||
ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
|
||||
|
||||
#ifdef PPP_FILTER
|
||||
set_filters(&pass_filter, &active_filter);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call the demand_conf procedure for each protocol that's got one.
|
||||
*/
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if (protp->enabled_flag && protp->demand_conf != NULL)
|
||||
if (!((*protp->demand_conf)(0)))
|
||||
die(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* demand_block - set each network protocol to block further packets.
|
||||
*/
|
||||
void
|
||||
demand_block()
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if (protp->enabled_flag && protp->demand_conf != NULL)
|
||||
sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
|
||||
get_loop_output();
|
||||
}
|
||||
|
||||
/*
|
||||
* demand_discard - set each network protocol to discard packets
|
||||
* with an error.
|
||||
*/
|
||||
void
|
||||
demand_discard()
|
||||
{
|
||||
struct packet *pkt, *nextpkt;
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if (protp->enabled_flag && protp->demand_conf != NULL)
|
||||
sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
|
||||
get_loop_output();
|
||||
|
||||
/* discard all saved packets */
|
||||
for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
|
||||
nextpkt = pkt->next;
|
||||
free(pkt);
|
||||
}
|
||||
pend_q = NULL;
|
||||
framelen = 0;
|
||||
flush_flag = 0;
|
||||
escape_flag = 0;
|
||||
fcs = PPP_INITFCS;
|
||||
}
|
||||
|
||||
/*
|
||||
* demand_unblock - set each enabled network protocol to pass packets.
|
||||
*/
|
||||
void
|
||||
demand_unblock()
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if (protp->enabled_flag && protp->demand_conf != NULL)
|
||||
sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
|
||||
}
|
||||
|
||||
/*
|
||||
* FCS lookup table as calculated by genfcstab.
|
||||
*/
|
||||
static u_short fcstab[256] = {
|
||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
||||
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
||||
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
||||
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
||||
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
||||
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
||||
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
||||
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
||||
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
||||
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
||||
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
||||
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
||||
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
||||
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
||||
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
||||
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
||||
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
||||
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
||||
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
||||
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
||||
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
||||
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
||||
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
||||
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
||||
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
||||
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
||||
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
||||
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
||||
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
||||
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
/*
|
||||
* loop_chars - process characters received from the loopback.
|
||||
* Calls loop_frame when a complete frame has been accumulated.
|
||||
* Return value is 1 if we need to bring up the link, 0 otherwise.
|
||||
*/
|
||||
int
|
||||
loop_chars(p, n)
|
||||
unsigned char *p;
|
||||
int n;
|
||||
{
|
||||
int c, rv;
|
||||
|
||||
rv = 0;
|
||||
for (; n > 0; --n) {
|
||||
c = *p++;
|
||||
if (c == PPP_FLAG) {
|
||||
if (!escape_flag && !flush_flag
|
||||
&& framelen > 2 && fcs == PPP_GOODFCS) {
|
||||
framelen -= 2;
|
||||
if (loop_frame(frame, framelen))
|
||||
rv = 1;
|
||||
}
|
||||
framelen = 0;
|
||||
flush_flag = 0;
|
||||
escape_flag = 0;
|
||||
fcs = PPP_INITFCS;
|
||||
continue;
|
||||
}
|
||||
if (flush_flag)
|
||||
continue;
|
||||
if (escape_flag) {
|
||||
c ^= PPP_TRANS;
|
||||
escape_flag = 0;
|
||||
} else if (c == PPP_ESCAPE) {
|
||||
escape_flag = 1;
|
||||
continue;
|
||||
}
|
||||
if (framelen >= framemax) {
|
||||
flush_flag = 1;
|
||||
continue;
|
||||
}
|
||||
frame[framelen++] = c;
|
||||
fcs = PPP_FCS(fcs, c);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* loop_frame - given a frame obtained from the loopback,
|
||||
* decide whether to bring up the link or not, and, if we want
|
||||
* to transmit this frame later, put it on the pending queue.
|
||||
* Return value is 1 if we need to bring up the link, 0 otherwise.
|
||||
* We assume that the kernel driver has already applied the
|
||||
* pass_filter, so we won't get packets it rejected.
|
||||
* We apply the active_filter to see if we want this packet to
|
||||
* bring up the link.
|
||||
*/
|
||||
int
|
||||
loop_frame(frame, len)
|
||||
unsigned char *frame;
|
||||
int len;
|
||||
{
|
||||
struct packet *pkt;
|
||||
|
||||
/* log_packet(frame, len, "from loop: ", LOG_DEBUG); */
|
||||
if (len < PPP_HDRLEN)
|
||||
return 0;
|
||||
if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
|
||||
return 0; /* shouldn't get any of these anyway */
|
||||
if (!active_packet(frame, len))
|
||||
return 0;
|
||||
|
||||
pkt = (struct packet *) malloc(sizeof(struct packet) + len);
|
||||
if (pkt != NULL) {
|
||||
pkt->length = len;
|
||||
pkt->next = NULL;
|
||||
memcpy(pkt->data, frame, len);
|
||||
if (pend_q == NULL)
|
||||
pend_q = pkt;
|
||||
else
|
||||
pend_qtail->next = pkt;
|
||||
pend_qtail = pkt;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* demand_rexmit - Resend all those frames which we got via the
|
||||
* loopback, now that the real serial link is up.
|
||||
*/
|
||||
void
|
||||
demand_rexmit(proto)
|
||||
int proto;
|
||||
{
|
||||
struct packet *pkt, *prev, *nextpkt;
|
||||
|
||||
prev = NULL;
|
||||
pkt = pend_q;
|
||||
pend_q = NULL;
|
||||
for (; pkt != NULL; pkt = nextpkt) {
|
||||
nextpkt = pkt->next;
|
||||
if (PPP_PROTOCOL(pkt->data) == proto) {
|
||||
output(0, pkt->data, pkt->length);
|
||||
free(pkt);
|
||||
} else {
|
||||
if (prev == NULL)
|
||||
pend_q = pkt;
|
||||
else
|
||||
prev->next = pkt;
|
||||
prev = pkt;
|
||||
}
|
||||
}
|
||||
pend_qtail = prev;
|
||||
if (prev != NULL)
|
||||
prev->next = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan a packet to decide whether it is an "active" packet,
|
||||
* that is, whether it is worth bringing up the link for.
|
||||
*/
|
||||
static int
|
||||
active_packet(p, len)
|
||||
unsigned char *p;
|
||||
int len;
|
||||
{
|
||||
int proto, i;
|
||||
struct protent *protp;
|
||||
|
||||
if (len < PPP_HDRLEN)
|
||||
return 0;
|
||||
proto = PPP_PROTOCOL(p);
|
||||
#ifdef PPP_FILTER
|
||||
if (active_filter.bf_len != 0
|
||||
&& bpf_filter(active_filter.bf_insns, frame, len, len) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i) {
|
||||
if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
|
||||
if (!protp->enabled_flag)
|
||||
return 0;
|
||||
if (protp->active_pkt == NULL)
|
||||
return 1;
|
||||
return (*protp->active_pkt)(p, len);
|
||||
}
|
||||
}
|
||||
return 0; /* not a supported protocol !!?? */
|
||||
}
|
||||
798
c/src/libnetworking/pppd/fsm.c
Normal file
798
c/src/libnetworking/pppd/fsm.c
Normal file
@@ -0,0 +1,798 @@
|
||||
/*
|
||||
* fsm.c - {Link, IP} Control Protocol Finite State Machine.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
#define log_packet(p, len, prefix, level)
|
||||
/*
|
||||
* TODO:
|
||||
* Randomize fsm id on link/init.
|
||||
* Deal with variable outgoing MTU.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
|
||||
static void fsm_timeout __P((void *));
|
||||
static void fsm_rconfreq __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfack __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int));
|
||||
static void fsm_rtermreq __P((fsm *, int, u_char *, int));
|
||||
static void fsm_rtermack __P((fsm *));
|
||||
static void fsm_rcoderej __P((fsm *, u_char *, int));
|
||||
static void fsm_sconfreq __P((fsm *, int));
|
||||
|
||||
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
|
||||
|
||||
int peer_mru[NUM_PPP];
|
||||
|
||||
|
||||
/*
|
||||
* fsm_init - Initialize fsm.
|
||||
*
|
||||
* Initialize fsm state.
|
||||
*/
|
||||
void
|
||||
fsm_init(f)
|
||||
fsm *f;
|
||||
{
|
||||
f->state = INITIAL;
|
||||
f->flags = 0;
|
||||
f->id = 0; /* XXX Start with random id? */
|
||||
f->timeouttime = DEFTIMEOUT;
|
||||
f->maxconfreqtransmits = DEFMAXCONFREQS;
|
||||
f->maxtermtransmits = DEFMAXTERMREQS;
|
||||
f->maxnakloops = DEFMAXNAKLOOPS;
|
||||
f->term_reason_len = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_lowerup - The lower layer is up.
|
||||
*/
|
||||
void
|
||||
fsm_lowerup(f)
|
||||
fsm *f;
|
||||
{
|
||||
switch( f->state ){
|
||||
case INITIAL:
|
||||
f->state = CLOSED;
|
||||
break;
|
||||
|
||||
case STARTING:
|
||||
if( f->flags & OPT_SILENT )
|
||||
f->state = STOPPED;
|
||||
else {
|
||||
/* Send an initial configure-request */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Up event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_lowerdown - The lower layer is down.
|
||||
*
|
||||
* Cancel all timeouts and inform upper layers.
|
||||
*/
|
||||
void
|
||||
fsm_lowerdown(f)
|
||||
fsm *f;
|
||||
{
|
||||
switch( f->state ){
|
||||
case CLOSED:
|
||||
f->state = INITIAL;
|
||||
break;
|
||||
|
||||
case STOPPED:
|
||||
f->state = STARTING;
|
||||
if( f->callbacks->starting )
|
||||
(*f->callbacks->starting)(f);
|
||||
break;
|
||||
|
||||
case CLOSING:
|
||||
f->state = INITIAL;
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
break;
|
||||
|
||||
case STOPPING:
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
f->state = STARTING;
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f);
|
||||
f->state = STARTING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Down event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_open - Link is allowed to come up.
|
||||
*/
|
||||
void
|
||||
fsm_open(f)
|
||||
fsm *f;
|
||||
{
|
||||
switch( f->state ){
|
||||
case INITIAL:
|
||||
f->state = STARTING;
|
||||
if( f->callbacks->starting )
|
||||
(*f->callbacks->starting)(f);
|
||||
break;
|
||||
|
||||
case CLOSED:
|
||||
if( f->flags & OPT_SILENT )
|
||||
f->state = STOPPED;
|
||||
else {
|
||||
/* Send an initial configure-request */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLOSING:
|
||||
f->state = STOPPING;
|
||||
/* fall through */
|
||||
case STOPPED:
|
||||
case OPENED:
|
||||
if( f->flags & OPT_RESTART ){
|
||||
fsm_lowerdown(f);
|
||||
fsm_lowerup(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_close - Start closing connection.
|
||||
*
|
||||
* Cancel timeouts and either initiate close or possibly go directly to
|
||||
* the CLOSED state.
|
||||
*/
|
||||
void
|
||||
fsm_close(f, reason)
|
||||
fsm *f;
|
||||
char *reason;
|
||||
{
|
||||
f->term_reason = reason;
|
||||
f->term_reason_len = (reason == NULL? 0: strlen(reason));
|
||||
switch( f->state ){
|
||||
case STARTING:
|
||||
f->state = INITIAL;
|
||||
break;
|
||||
case STOPPED:
|
||||
f->state = CLOSED;
|
||||
break;
|
||||
case STOPPING:
|
||||
f->state = CLOSING;
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
case OPENED:
|
||||
if( f->state != OPENED )
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
else if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f); /* Inform upper layers we're down */
|
||||
|
||||
/* Init restart counter, send Terminate-Request */
|
||||
f->retransmits = f->maxtermtransmits;
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
|
||||
f->state = CLOSING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_timeout - Timeout expired.
|
||||
*/
|
||||
static void
|
||||
fsm_timeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
fsm *f = (fsm *) arg;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSING:
|
||||
case STOPPING:
|
||||
if( f->retransmits <= 0 ){
|
||||
/*
|
||||
* We've waited for an ack long enough. Peer probably heard us.
|
||||
*/
|
||||
f->state = (f->state == CLOSING)? CLOSED: STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
} else {
|
||||
/* Send Terminate-Request */
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
}
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
if (f->retransmits <= 0) {
|
||||
syslog(LOG_WARNING, "%s: timeout sending Config-Requests",
|
||||
PROTO_NAME(f));
|
||||
f->state = STOPPED;
|
||||
if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
|
||||
} else {
|
||||
/* Retransmit the configure-request */
|
||||
if (f->callbacks->retransmit)
|
||||
(*f->callbacks->retransmit)(f);
|
||||
fsm_sconfreq(f, 1); /* Re-send Configure-Request */
|
||||
if( f->state == ACKRCVD )
|
||||
f->state = REQSENT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_input - Input packet.
|
||||
*/
|
||||
void
|
||||
fsm_input(f, inpacket, l)
|
||||
fsm *f;
|
||||
u_char *inpacket;
|
||||
int l;
|
||||
{
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Parse header (code, id and length).
|
||||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (l < HEADERLEN) {
|
||||
FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < HEADERLEN) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
if (len > l) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
len -= HEADERLEN; /* subtract header length */
|
||||
|
||||
if( f->state == INITIAL || f->state == STARTING ){
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d.",
|
||||
f->protocol, f->state));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Action depends on code.
|
||||
*/
|
||||
switch (code) {
|
||||
case CONFREQ:
|
||||
fsm_rconfreq(f, id, inp, len);
|
||||
break;
|
||||
|
||||
case CONFACK:
|
||||
fsm_rconfack(f, id, inp, len);
|
||||
break;
|
||||
|
||||
case CONFNAK:
|
||||
case CONFREJ:
|
||||
fsm_rconfnakrej(f, code, id, inp, len);
|
||||
break;
|
||||
|
||||
case TERMREQ:
|
||||
fsm_rtermreq(f, id, inp, len);
|
||||
break;
|
||||
|
||||
case TERMACK:
|
||||
fsm_rtermack(f);
|
||||
break;
|
||||
|
||||
case CODEREJ:
|
||||
fsm_rcoderej(f, inp, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !f->callbacks->extcode
|
||||
|| !(*f->callbacks->extcode)(f, code, id, inp, len) )
|
||||
fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfreq - Receive Configure-Request.
|
||||
*/
|
||||
static void
|
||||
fsm_rconfreq(f, id, inp, len)
|
||||
fsm *f;
|
||||
u_char id;
|
||||
u_char *inp;
|
||||
int len;
|
||||
{
|
||||
int code, reject_if_disagree;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d.", PROTO_NAME(f), id));
|
||||
switch( f->state ){
|
||||
case CLOSED:
|
||||
/* Go away, we're closed */
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
return;
|
||||
case CLOSING:
|
||||
case STOPPING:
|
||||
return;
|
||||
|
||||
case OPENED:
|
||||
/* Go down and restart negotiation */
|
||||
if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
break;
|
||||
|
||||
case STOPPED:
|
||||
/* Negotiation started by our peer */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass the requested configuration options
|
||||
* to protocol-specific code for checking.
|
||||
*/
|
||||
if (f->callbacks->reqci){ /* Check CI */
|
||||
reject_if_disagree = (f->nakloops >= f->maxnakloops);
|
||||
code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
|
||||
} else if (len)
|
||||
code = CONFREJ; /* Reject all CI */
|
||||
else
|
||||
code = CONFACK;
|
||||
|
||||
/* send the Ack, Nak or Rej to the peer */
|
||||
fsm_sdata(f, code, id, inp, len);
|
||||
|
||||
if (code == CONFACK) {
|
||||
if (f->state == ACKRCVD) {
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
f->state = OPENED;
|
||||
if (f->callbacks->up)
|
||||
(*f->callbacks->up)(f); /* Inform upper layers */
|
||||
} else
|
||||
f->state = ACKSENT;
|
||||
f->nakloops = 0;
|
||||
|
||||
} else {
|
||||
/* we sent CONFACK or CONFREJ */
|
||||
if (f->state != ACKRCVD)
|
||||
f->state = REQSENT;
|
||||
if( code == CONFNAK )
|
||||
++f->nakloops;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfack - Receive Configure-Ack.
|
||||
*/
|
||||
static void
|
||||
fsm_rconfack(f, id, inp, len)
|
||||
fsm *f;
|
||||
int id;
|
||||
u_char *inp;
|
||||
int len;
|
||||
{
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
if (id != f->reqid || f->seen_ack) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
|
||||
(len == 0)) ){
|
||||
/* Ack is bad - ignore it */
|
||||
log_packet(inp, len, "Received bad configure-ack: ", LOG_ERR);
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
|
||||
PROTO_NAME(f), len));
|
||||
return;
|
||||
}
|
||||
f->seen_ack = 1;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSED:
|
||||
case STOPPED:
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
f->state = ACKRCVD;
|
||||
f->retransmits = f->maxconfreqtransmits;
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
/* Huh? an extra valid Ack? oh well... */
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
|
||||
case ACKSENT:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
f->state = OPENED;
|
||||
f->retransmits = f->maxconfreqtransmits;
|
||||
if (f->callbacks->up)
|
||||
(*f->callbacks->up)(f); /* Inform upper layers */
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
/* Go down and restart negotiation */
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
|
||||
*/
|
||||
static void
|
||||
fsm_rconfnakrej(f, code, id, inp, len)
|
||||
fsm *f;
|
||||
int code, id;
|
||||
u_char *inp;
|
||||
int len;
|
||||
{
|
||||
int (*proc) __P((fsm *, u_char *, int));
|
||||
int ret;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
if (id != f->reqid || f->seen_ack) /* Expected id? */
|
||||
return; /* Nope, toss... */
|
||||
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
|
||||
if (!proc || !(ret = proc(f, inp, len))) {
|
||||
/* Nak/reject is bad - ignore it */
|
||||
log_packet(inp, len, "Received bad configure-nak/rej: ", LOG_ERR);
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
|
||||
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
|
||||
return;
|
||||
}
|
||||
f->seen_ack = 1;
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSED:
|
||||
case STOPPED:
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
break;
|
||||
|
||||
case REQSENT:
|
||||
case ACKSENT:
|
||||
/* They didn't agree to what we wanted - try another request */
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
if (ret < 0)
|
||||
f->state = STOPPED; /* kludge for stopping CCP */
|
||||
else
|
||||
fsm_sconfreq(f, 0); /* Send Configure-Request */
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
/* Got a Nak/reject when we had already had an Ack?? oh well... */
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
fsm_sconfreq(f, 0);
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
/* Go down and restart negotiation */
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0); /* Send initial Configure-Request */
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rtermreq - Receive Terminate-Req.
|
||||
*/
|
||||
static void
|
||||
fsm_rtermreq(f, id, p, len)
|
||||
fsm *f;
|
||||
int id;
|
||||
u_char *p;
|
||||
int len;
|
||||
{
|
||||
char str[80];
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
|
||||
PROTO_NAME(f), id));
|
||||
|
||||
switch (f->state) {
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
f->state = REQSENT; /* Start over but keep trying */
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if (len > 0) {
|
||||
fmtmsg(str, sizeof(str), "%0.*v", len, p);
|
||||
syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str);
|
||||
} else
|
||||
syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f));
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
f->retransmits = 0;
|
||||
f->state = STOPPING;
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
break;
|
||||
}
|
||||
|
||||
fsm_sdata(f, TERMACK, id, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rtermack - Receive Terminate-Ack.
|
||||
*/
|
||||
static void
|
||||
fsm_rtermack(f)
|
||||
fsm *f;
|
||||
{
|
||||
FSMDEBUG((LOG_INFO, "fsm_rtermack(%s).", PROTO_NAME(f)));
|
||||
|
||||
switch (f->state) {
|
||||
case CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, f);
|
||||
f->state = CLOSED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
case STOPPING:
|
||||
UNTIMEOUT(fsm_timeout, f);
|
||||
f->state = STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
|
||||
case ACKRCVD:
|
||||
f->state = REQSENT;
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if (f->callbacks->down)
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
fsm_sconfreq(f, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rcoderej - Receive an Code-Reject.
|
||||
*/
|
||||
static void
|
||||
fsm_rcoderej(f, inp, len)
|
||||
fsm *f;
|
||||
u_char *inp;
|
||||
int len;
|
||||
{
|
||||
u_char code, id;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s).", PROTO_NAME(f)));
|
||||
|
||||
if (len < HEADERLEN) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
syslog(LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d",
|
||||
PROTO_NAME(f), code, id);
|
||||
|
||||
if( f->state == ACKRCVD )
|
||||
f->state = REQSENT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_protreject - Peer doesn't speak this protocol.
|
||||
*
|
||||
* Treat this as a catastrophic error (RXJ-).
|
||||
*/
|
||||
void
|
||||
fsm_protreject(f)
|
||||
fsm *f;
|
||||
{
|
||||
switch( f->state ){
|
||||
case CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case CLOSED:
|
||||
f->state = CLOSED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
|
||||
case STOPPING:
|
||||
case REQSENT:
|
||||
case ACKRCVD:
|
||||
case ACKSENT:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case STOPPED:
|
||||
f->state = STOPPED;
|
||||
if( f->callbacks->finished )
|
||||
(*f->callbacks->finished)(f);
|
||||
break;
|
||||
|
||||
case OPENED:
|
||||
if( f->callbacks->down )
|
||||
(*f->callbacks->down)(f);
|
||||
|
||||
/* Init restart counter, send Terminate-Request */
|
||||
f->retransmits = f->maxtermtransmits;
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
|
||||
f->state = STOPPING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d!",
|
||||
PROTO_NAME(f), f->state));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sconfreq - Send a Configure-Request.
|
||||
*/
|
||||
static void
|
||||
fsm_sconfreq(f, retransmit)
|
||||
fsm *f;
|
||||
int retransmit;
|
||||
{
|
||||
u_char *outp;
|
||||
int cilen;
|
||||
|
||||
if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){
|
||||
/* Not currently negotiating - reset options */
|
||||
if( f->callbacks->resetci )
|
||||
(*f->callbacks->resetci)(f);
|
||||
f->nakloops = 0;
|
||||
}
|
||||
|
||||
if( !retransmit ){
|
||||
/* New request - reset retransmission counter, use new ID */
|
||||
f->retransmits = f->maxconfreqtransmits;
|
||||
f->reqid = ++f->id;
|
||||
}
|
||||
|
||||
f->seen_ack = 0;
|
||||
|
||||
/*
|
||||
* Make up the request packet
|
||||
*/
|
||||
outp = outpacket_buf + PPP_HDRLEN + HEADERLEN;
|
||||
if( f->callbacks->cilen && f->callbacks->addci ){
|
||||
cilen = (*f->callbacks->cilen)(f);
|
||||
if( cilen > peer_mru[f->unit] - HEADERLEN )
|
||||
cilen = peer_mru[f->unit] - HEADERLEN;
|
||||
if (f->callbacks->addci)
|
||||
(*f->callbacks->addci)(f, outp, &cilen);
|
||||
} else
|
||||
cilen = 0;
|
||||
|
||||
/* send the request to our peer */
|
||||
fsm_sdata(f, CONFREQ, f->reqid, outp, cilen);
|
||||
|
||||
/* start the retransmit timer */
|
||||
--f->retransmits;
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d",
|
||||
PROTO_NAME(f), f->reqid));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sdata - Send some data.
|
||||
*
|
||||
* Used for all packets sent to our peer by this module.
|
||||
*/
|
||||
void
|
||||
fsm_sdata(f, code, id, data, datalen)
|
||||
fsm *f;
|
||||
u_char code, id;
|
||||
u_char *data;
|
||||
int datalen;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
/* Adjust length to be smaller than MTU */
|
||||
outp = outpacket_buf;
|
||||
if (datalen > peer_mru[f->unit] - HEADERLEN)
|
||||
datalen = peer_mru[f->unit] - HEADERLEN;
|
||||
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN)
|
||||
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
|
||||
outlen = datalen + HEADERLEN;
|
||||
MAKEHEADER(outp, f->protocol);
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
output(f->unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d, id %d.",
|
||||
PROTO_NAME(f), code, id));
|
||||
}
|
||||
144
c/src/libnetworking/pppd/fsm.h
Normal file
144
c/src/libnetworking/pppd/fsm.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Packet header = Code, id, length.
|
||||
*/
|
||||
#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
|
||||
|
||||
|
||||
/*
|
||||
* CP (LCP, IPCP, etc.) codes.
|
||||
*/
|
||||
#define CONFREQ 1 /* Configuration Request */
|
||||
#define CONFACK 2 /* Configuration Ack */
|
||||
#define CONFNAK 3 /* Configuration Nak */
|
||||
#define CONFREJ 4 /* Configuration Reject */
|
||||
#define TERMREQ 5 /* Termination Request */
|
||||
#define TERMACK 6 /* Termination Ack */
|
||||
#define CODEREJ 7 /* Code Reject */
|
||||
|
||||
|
||||
/*
|
||||
* Each FSM is described by an fsm structure and fsm callbacks.
|
||||
*/
|
||||
typedef struct fsm {
|
||||
int unit; /* Interface unit number */
|
||||
int protocol; /* Data Link Layer Protocol field value */
|
||||
int state; /* State */
|
||||
int flags; /* Contains option bits */
|
||||
u_char id; /* Current id */
|
||||
u_char reqid; /* Current request id */
|
||||
u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */
|
||||
int timeouttime; /* Timeout time in milliseconds */
|
||||
int maxconfreqtransmits; /* Maximum Configure-Request transmissions */
|
||||
int retransmits; /* Number of retransmissions left */
|
||||
int maxtermtransmits; /* Maximum Terminate-Request transmissions */
|
||||
int nakloops; /* Number of nak loops since last ack */
|
||||
int maxnakloops; /* Maximum number of nak loops tolerated */
|
||||
struct fsm_callbacks *callbacks; /* Callback routines */
|
||||
char *term_reason; /* Reason for closing protocol */
|
||||
int term_reason_len; /* Length of term_reason */
|
||||
} fsm;
|
||||
|
||||
|
||||
typedef struct fsm_callbacks {
|
||||
void (*resetci) /* Reset our Configuration Information */
|
||||
__P((fsm *));
|
||||
int (*cilen) /* Length of our Configuration Information */
|
||||
__P((fsm *));
|
||||
void (*addci) /* Add our Configuration Information */
|
||||
__P((fsm *, u_char *, int *));
|
||||
int (*ackci) /* ACK our Configuration Information */
|
||||
__P((fsm *, u_char *, int));
|
||||
int (*nakci) /* NAK our Configuration Information */
|
||||
__P((fsm *, u_char *, int));
|
||||
int (*rejci) /* Reject our Configuration Information */
|
||||
__P((fsm *, u_char *, int));
|
||||
int (*reqci) /* Request peer's Configuration Information */
|
||||
__P((fsm *, u_char *, int *, int));
|
||||
void (*up) /* Called when fsm reaches OPENED state */
|
||||
__P((fsm *));
|
||||
void (*down) /* Called when fsm leaves OPENED state */
|
||||
__P((fsm *));
|
||||
void (*starting) /* Called when we want the lower layer */
|
||||
__P((fsm *));
|
||||
void (*finished) /* Called when we don't want the lower layer */
|
||||
__P((fsm *));
|
||||
void (*protreject) /* Called when Protocol-Reject received */
|
||||
__P((int));
|
||||
void (*retransmit) /* Retransmission is necessary */
|
||||
__P((fsm *));
|
||||
int (*extcode) /* Called when unknown code received */
|
||||
__P((fsm *, int, int, u_char *, int));
|
||||
char *proto_name; /* String name for protocol (for messages) */
|
||||
} fsm_callbacks;
|
||||
|
||||
|
||||
/*
|
||||
* Link states.
|
||||
*/
|
||||
#define INITIAL 0 /* Down, hasn't been opened */
|
||||
#define STARTING 1 /* Down, been opened */
|
||||
#define CLOSED 2 /* Up, hasn't been opened */
|
||||
#define STOPPED 3 /* Open, waiting for down event */
|
||||
#define CLOSING 4 /* Terminating the connection, not open */
|
||||
#define STOPPING 5 /* Terminating, but open */
|
||||
#define REQSENT 6 /* We've sent a Config Request */
|
||||
#define ACKRCVD 7 /* We've received a Config Ack */
|
||||
#define ACKSENT 8 /* We've sent a Config Ack */
|
||||
#define OPENED 9 /* Connection available */
|
||||
|
||||
|
||||
/*
|
||||
* Flags - indicate options controlling FSM operation
|
||||
*/
|
||||
#define OPT_PASSIVE 1 /* Don't die if we don't get a response */
|
||||
#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */
|
||||
#define OPT_SILENT 4 /* Wait for peer to speak first */
|
||||
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define DEFTIMEOUT 3 /* Timeout time in seconds */
|
||||
#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */
|
||||
#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */
|
||||
#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
void fsm_init __P((fsm *));
|
||||
void fsm_lowerup __P((fsm *));
|
||||
void fsm_lowerdown __P((fsm *));
|
||||
void fsm_open __P((fsm *));
|
||||
void fsm_close __P((fsm *, char *));
|
||||
void fsm_input __P((fsm *, u_char *, int));
|
||||
void fsm_protreject __P((fsm *));
|
||||
void fsm_sdata __P((fsm *, int, int, u_char *, int));
|
||||
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */
|
||||
1506
c/src/libnetworking/pppd/ipcp.c
Normal file
1506
c/src/libnetworking/pppd/ipcp.c
Normal file
File diff suppressed because it is too large
Load Diff
70
c/src/libnetworking/pppd/ipcp.h
Normal file
70
c/src/libnetworking/pppd/ipcp.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* ipcp.h - IP Control Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
#define CI_ADDRS 1 /* IP Addresses */
|
||||
#define CI_COMPRESSTYPE 2 /* Compression Type */
|
||||
#define CI_ADDR 3
|
||||
|
||||
#define CI_MS_DNS1 129 /* Primary DNS value */
|
||||
#define CI_MS_WINS1 130 /* Primary WINS value */
|
||||
#define CI_MS_DNS2 131 /* Secondary DNS value */
|
||||
#define CI_MS_WINS2 132 /* Secondary WINS value */
|
||||
|
||||
#define MAX_STATES 16 /* from slcompress.h */
|
||||
|
||||
#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */
|
||||
#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */
|
||||
#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */
|
||||
/* maxslot and slot number compression) */
|
||||
|
||||
#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/
|
||||
#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */
|
||||
/* compression option*/
|
||||
|
||||
typedef struct ipcp_options {
|
||||
int neg_addr : 1; /* Negotiate IP Address? */
|
||||
int old_addrs : 1; /* Use old (IP-Addresses) option? */
|
||||
int req_addr : 1; /* Ask peer to send IP address? */
|
||||
int default_route : 1; /* Assign default route through interface? */
|
||||
int proxy_arp : 1; /* Make proxy ARP entry for peer? */
|
||||
int neg_vj : 1; /* Van Jacobson Compression? */
|
||||
int old_vj : 1; /* use old (short) form of VJ option? */
|
||||
int accept_local : 1; /* accept peer's value for ouraddr */
|
||||
int accept_remote : 1; /* accept peer's value for hisaddr */
|
||||
u_short vj_protocol; /* protocol value to use in VJ option */
|
||||
u_char maxslotindex, cflag; /* values for RFC1332 VJ compression neg. */
|
||||
u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */
|
||||
u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */
|
||||
u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */
|
||||
} ipcp_options;
|
||||
|
||||
extern fsm ipcp_fsm[];
|
||||
extern ipcp_options ipcp_wantoptions[];
|
||||
extern ipcp_options ipcp_gotoptions[];
|
||||
extern ipcp_options ipcp_allowoptions[];
|
||||
extern ipcp_options ipcp_hisoptions[];
|
||||
|
||||
char *ip_ntoa __P((u_int32_t));
|
||||
|
||||
extern struct protent ipcp_protent;
|
||||
1399
c/src/libnetworking/pppd/ipxcp.c
Normal file
1399
c/src/libnetworking/pppd/ipxcp.c
Normal file
File diff suppressed because it is too large
Load Diff
71
c/src/libnetworking/pppd/ipxcp.h
Normal file
71
c/src/libnetworking/pppd/ipxcp.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* ipxcp.h - IPX Control Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
#define IPX_NETWORK_NUMBER 1 /* IPX Network Number */
|
||||
#define IPX_NODE_NUMBER 2
|
||||
#define IPX_COMPRESSION_PROTOCOL 3
|
||||
#define IPX_ROUTER_PROTOCOL 4
|
||||
#define IPX_ROUTER_NAME 5
|
||||
#define IPX_COMPLETE 6
|
||||
|
||||
/* Values for the router protocol */
|
||||
#define IPX_NONE 0
|
||||
#define RIP_SAP 2
|
||||
#define NLSP 4
|
||||
|
||||
typedef struct ipxcp_options {
|
||||
int neg_node : 1; /* Negotiate IPX node number? */
|
||||
int req_node : 1; /* Ask peer to send IPX node number? */
|
||||
|
||||
int neg_nn : 1; /* Negotiate IPX network number? */
|
||||
int req_nn : 1; /* Ask peer to send IPX network number */
|
||||
|
||||
int neg_name : 1; /* Negotiate IPX router name */
|
||||
int neg_complete : 1; /* Negotiate completion */
|
||||
int neg_router : 1; /* Negotiate IPX router number */
|
||||
|
||||
int accept_local : 1; /* accept peer's value for ournode */
|
||||
int accept_remote : 1; /* accept peer's value for hisnode */
|
||||
int accept_network : 1; /* accept network number */
|
||||
|
||||
int tried_nlsp : 1; /* I have suggested NLSP already */
|
||||
int tried_rip : 1; /* I have suggested RIP/SAP already */
|
||||
|
||||
u_int32_t his_network; /* base network number */
|
||||
u_int32_t our_network; /* our value for network number */
|
||||
u_int32_t network; /* the final network number */
|
||||
|
||||
u_char his_node[6]; /* peer's node number */
|
||||
u_char our_node[6]; /* our node number */
|
||||
u_char name [48]; /* name of the router */
|
||||
int router; /* routing protocol */
|
||||
} ipxcp_options;
|
||||
|
||||
extern fsm ipxcp_fsm[];
|
||||
extern ipxcp_options ipxcp_wantoptions[];
|
||||
extern ipxcp_options ipxcp_gotoptions[];
|
||||
extern ipxcp_options ipxcp_allowoptions[];
|
||||
extern ipxcp_options ipxcp_hisoptions[];
|
||||
|
||||
extern struct protent ipxcp_protent;
|
||||
1858
c/src/libnetworking/pppd/lcp.c
Normal file
1858
c/src/libnetworking/pppd/lcp.c
Normal file
File diff suppressed because it is too large
Load Diff
88
c/src/libnetworking/pppd/lcp.h
Normal file
88
c/src/libnetworking/pppd/lcp.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* lcp.h - Link Control Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
#define CI_MRU 1 /* Maximum Receive Unit */
|
||||
#define CI_ASYNCMAP 2 /* Async Control Character Map */
|
||||
#define CI_AUTHTYPE 3 /* Authentication Type */
|
||||
#define CI_QUALITY 4 /* Quality Protocol */
|
||||
#define CI_MAGICNUMBER 5 /* Magic Number */
|
||||
#define CI_PCOMPRESSION 7 /* Protocol Field Compression */
|
||||
#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
|
||||
#define CI_CALLBACK 13 /* callback */
|
||||
|
||||
/*
|
||||
* LCP-specific packet types.
|
||||
*/
|
||||
#define PROTREJ 8 /* Protocol Reject */
|
||||
#define ECHOREQ 9 /* Echo Request */
|
||||
#define ECHOREP 10 /* Echo Reply */
|
||||
#define DISCREQ 11 /* Discard Request */
|
||||
#define CBCP_OPT 6 /* Use callback control protocol */
|
||||
|
||||
/*
|
||||
* The state of options is described by an lcp_options structure.
|
||||
*/
|
||||
typedef struct lcp_options {
|
||||
int passive : 1; /* Don't die if we don't get a response */
|
||||
int silent : 1; /* Wait for the other end to start first */
|
||||
int restart : 1; /* Restart vs. exit after close */
|
||||
int neg_mru : 1; /* Negotiate the MRU? */
|
||||
int neg_asyncmap : 1; /* Negotiate the async map? */
|
||||
int neg_upap : 1; /* Ask for UPAP authentication? */
|
||||
int neg_chap : 1; /* Ask for CHAP authentication? */
|
||||
int neg_magicnumber : 1; /* Ask for magic number? */
|
||||
int neg_pcompression : 1; /* HDLC Protocol Field Compression? */
|
||||
int neg_accompression : 1; /* HDLC Address/Control Field Compression? */
|
||||
int neg_lqr : 1; /* Negotiate use of Link Quality Reports */
|
||||
int neg_cbcp : 1; /* Negotiate use of CBCP */
|
||||
u_short mru; /* Value of MRU */
|
||||
u_char chap_mdtype; /* which MD type (hashing algorithm) */
|
||||
u_int32_t asyncmap; /* Value of async map */
|
||||
u_int32_t magicnumber;
|
||||
int numloops; /* Number of loops during magic number neg. */
|
||||
u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */
|
||||
} lcp_options;
|
||||
|
||||
extern fsm lcp_fsm[];
|
||||
extern lcp_options lcp_wantoptions[];
|
||||
extern lcp_options lcp_gotoptions[];
|
||||
extern lcp_options lcp_allowoptions[];
|
||||
extern lcp_options lcp_hisoptions[];
|
||||
extern u_int32_t xmit_accm[][8];
|
||||
|
||||
#define DEFMRU 1500 /* Try for this */
|
||||
#define MINMRU 128 /* No MRUs below this */
|
||||
#define MAXMRU 16384 /* Normally limit MRU to this */
|
||||
|
||||
void lcp_open __P((int));
|
||||
void lcp_close __P((int, char *));
|
||||
void lcp_lowerup __P((int));
|
||||
void lcp_lowerdown __P((int));
|
||||
void lcp_sprotrej __P((int, u_char *, int)); /* send protocol reject */
|
||||
|
||||
extern struct protent lcp_protent;
|
||||
|
||||
/* Default number of times we receive our magic number from the peer
|
||||
before deciding the link is looped-back. */
|
||||
#define DEFLOOPBACKFAIL 10
|
||||
86
c/src/libnetworking/pppd/magic.c
Normal file
86
c/src/libnetworking/pppd/magic.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* magic.c - PPP Magic Number routines.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "magic.h"
|
||||
|
||||
extern long mrand48 __P((void));
|
||||
extern void srand48 __P((long));
|
||||
|
||||
/*
|
||||
* magic_init - Initialize the magic number generator.
|
||||
*
|
||||
* Attempts to compute a random number seed which will not repeat.
|
||||
* The current method uses the current hostid, current process ID
|
||||
* and current time, currently.
|
||||
*/
|
||||
void
|
||||
magic_init()
|
||||
{
|
||||
long seed;
|
||||
struct timeval t;
|
||||
|
||||
gettimeofday(&t, NULL);
|
||||
seed = get_host_seed() ^ t.tv_sec ^ t.tv_usec ^ getpid();
|
||||
srand48(seed);
|
||||
}
|
||||
|
||||
/*
|
||||
* magic - Returns the next magic number.
|
||||
*/
|
||||
u_int32_t
|
||||
magic()
|
||||
{
|
||||
return (u_int32_t) mrand48();
|
||||
}
|
||||
|
||||
/*
|
||||
* Substitute procedures for those systems which don't have
|
||||
* drand48 et al.
|
||||
*/
|
||||
/* #include <stdlib.h> */
|
||||
double
|
||||
drand48()
|
||||
{
|
||||
return (double)rand() / (double)0x7fffffffL; /* 2**31-1 */
|
||||
}
|
||||
|
||||
long
|
||||
mrand48()
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
void
|
||||
srand48(seedval)
|
||||
long seedval;
|
||||
{
|
||||
srand((int)seedval);
|
||||
}
|
||||
|
||||
23
c/src/libnetworking/pppd/magic.h
Normal file
23
c/src/libnetworking/pppd/magic.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* magic.h - PPP Magic Number definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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$
|
||||
*/
|
||||
|
||||
void magic_init __P((void)); /* Initialize the magic number generator */
|
||||
u_int32_t magic __P((void)); /* Returns the next magic number */
|
||||
1283
c/src/libnetworking/pppd/main.c
Normal file
1283
c/src/libnetworking/pppd/main.c
Normal file
File diff suppressed because it is too large
Load Diff
298
c/src/libnetworking/pppd/md4.c
Normal file
298
c/src/libnetworking/pppd/md4.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
** ********************************************************************
|
||||
** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||
** Updated: 2/16/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
** To use MD4:
|
||||
** -- Include md4.h in your program
|
||||
** -- Declare an MDstruct MD to hold the state of the digest
|
||||
** computation.
|
||||
** -- Initialize MD using MDbegin(&MD)
|
||||
** -- For each full block (64 bytes) X you wish to process, call
|
||||
** MD4Update(&MD,X,512)
|
||||
** (512 is the number of bits in a full block.)
|
||||
** -- For the last block (less than 64 bytes) you wish to process,
|
||||
** MD4Update(&MD,X,n)
|
||||
** where n is the number of bits in the partial block. A partial
|
||||
** block terminates the computation, so every MD computation
|
||||
** should terminate by processing a partial block, even if it
|
||||
** has n = 0.
|
||||
** -- The message digest is available in MD.buffer[0] ...
|
||||
** MD.buffer[3]. (Least-significant byte of each word
|
||||
** should be output first.)
|
||||
** -- You can print out the digest using MDprint(&MD)
|
||||
*/
|
||||
|
||||
/* Implementation notes:
|
||||
** This implementation assumes that ints are 32-bit quantities.
|
||||
*/
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
/* Compile-time includes
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "md4.h"
|
||||
#include "pppd.h"
|
||||
|
||||
/* Compile-time declarations of MD4 "magic constants".
|
||||
*/
|
||||
#define I0 0x67452301 /* Initial values for MD buffer */
|
||||
#define I1 0xefcdab89
|
||||
#define I2 0x98badcfe
|
||||
#define I3 0x10325476
|
||||
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
|
||||
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
|
||||
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
|
||||
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
|
||||
** Table 2, page 660.
|
||||
*/
|
||||
|
||||
#define fs1 3 /* round 1 shift amounts */
|
||||
#define fs2 7
|
||||
#define fs3 11
|
||||
#define fs4 19
|
||||
#define gs1 3 /* round 2 shift amounts */
|
||||
#define gs2 5
|
||||
#define gs3 9
|
||||
#define gs4 13
|
||||
#define hs1 3 /* round 3 shift amounts */
|
||||
#define hs2 9
|
||||
#define hs3 11
|
||||
#define hs4 15
|
||||
|
||||
/* Compile-time macro declarations for MD4.
|
||||
** Note: The "rot" operator uses the variable "tmp".
|
||||
** It assumes tmp is declared as unsigned int, so that the >>
|
||||
** operator will shift in zeros rather than extending the sign bit.
|
||||
*/
|
||||
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
|
||||
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
|
||||
#define h(X,Y,Z) (X^Y^Z)
|
||||
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
|
||||
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
|
||||
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
|
||||
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
|
||||
|
||||
/* MD4print(MDp)
|
||||
** Print message digest buffer MDp as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte of
|
||||
** buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MD4Print(MDp)
|
||||
MD4_CTX *MDp;
|
||||
{
|
||||
int i,j;
|
||||
for (i=0;i<4;i++)
|
||||
for (j=0;j<32;j=j+8)
|
||||
printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
|
||||
}
|
||||
|
||||
/* MD4Init(MDp)
|
||||
** Initialize message digest buffer MDp.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MD4Init(MDp)
|
||||
MD4_CTX *MDp;
|
||||
{
|
||||
int i;
|
||||
MDp->buffer[0] = I0;
|
||||
MDp->buffer[1] = I1;
|
||||
MDp->buffer[2] = I2;
|
||||
MDp->buffer[3] = I3;
|
||||
for (i=0;i<8;i++) MDp->count[i] = 0;
|
||||
MDp->done = 0;
|
||||
}
|
||||
|
||||
/* MDblock(MDp,X)
|
||||
** Update message digest buffer MDp->buffer using 16-word data block X.
|
||||
** Assumes all 16 words of X are full of data.
|
||||
** Does not update MDp->count.
|
||||
** This routine is not user-callable.
|
||||
*/
|
||||
static void
|
||||
MDblock(MDp,Xb)
|
||||
MD4_CTX *MDp;
|
||||
unsigned char *Xb;
|
||||
{
|
||||
register unsigned int tmp, A, B, C, D;
|
||||
unsigned int X[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24);
|
||||
Xb += 4;
|
||||
}
|
||||
|
||||
A = MDp->buffer[0];
|
||||
B = MDp->buffer[1];
|
||||
C = MDp->buffer[2];
|
||||
D = MDp->buffer[3];
|
||||
/* Update the message digest buffer */
|
||||
ff(A , B , C , D , 0 , fs1); /* Round 1 */
|
||||
ff(D , A , B , C , 1 , fs2);
|
||||
ff(C , D , A , B , 2 , fs3);
|
||||
ff(B , C , D , A , 3 , fs4);
|
||||
ff(A , B , C , D , 4 , fs1);
|
||||
ff(D , A , B , C , 5 , fs2);
|
||||
ff(C , D , A , B , 6 , fs3);
|
||||
ff(B , C , D , A , 7 , fs4);
|
||||
ff(A , B , C , D , 8 , fs1);
|
||||
ff(D , A , B , C , 9 , fs2);
|
||||
ff(C , D , A , B , 10 , fs3);
|
||||
ff(B , C , D , A , 11 , fs4);
|
||||
ff(A , B , C , D , 12 , fs1);
|
||||
ff(D , A , B , C , 13 , fs2);
|
||||
ff(C , D , A , B , 14 , fs3);
|
||||
ff(B , C , D , A , 15 , fs4);
|
||||
gg(A , B , C , D , 0 , gs1); /* Round 2 */
|
||||
gg(D , A , B , C , 4 , gs2);
|
||||
gg(C , D , A , B , 8 , gs3);
|
||||
gg(B , C , D , A , 12 , gs4);
|
||||
gg(A , B , C , D , 1 , gs1);
|
||||
gg(D , A , B , C , 5 , gs2);
|
||||
gg(C , D , A , B , 9 , gs3);
|
||||
gg(B , C , D , A , 13 , gs4);
|
||||
gg(A , B , C , D , 2 , gs1);
|
||||
gg(D , A , B , C , 6 , gs2);
|
||||
gg(C , D , A , B , 10 , gs3);
|
||||
gg(B , C , D , A , 14 , gs4);
|
||||
gg(A , B , C , D , 3 , gs1);
|
||||
gg(D , A , B , C , 7 , gs2);
|
||||
gg(C , D , A , B , 11 , gs3);
|
||||
gg(B , C , D , A , 15 , gs4);
|
||||
hh(A , B , C , D , 0 , hs1); /* Round 3 */
|
||||
hh(D , A , B , C , 8 , hs2);
|
||||
hh(C , D , A , B , 4 , hs3);
|
||||
hh(B , C , D , A , 12 , hs4);
|
||||
hh(A , B , C , D , 2 , hs1);
|
||||
hh(D , A , B , C , 10 , hs2);
|
||||
hh(C , D , A , B , 6 , hs3);
|
||||
hh(B , C , D , A , 14 , hs4);
|
||||
hh(A , B , C , D , 1 , hs1);
|
||||
hh(D , A , B , C , 9 , hs2);
|
||||
hh(C , D , A , B , 5 , hs3);
|
||||
hh(B , C , D , A , 13 , hs4);
|
||||
hh(A , B , C , D , 3 , hs1);
|
||||
hh(D , A , B , C , 11 , hs2);
|
||||
hh(C , D , A , B , 7 , hs3);
|
||||
hh(B , C , D , A , 15 , hs4);
|
||||
MDp->buffer[0] += A;
|
||||
MDp->buffer[1] += B;
|
||||
MDp->buffer[2] += C;
|
||||
MDp->buffer[3] += D;
|
||||
}
|
||||
|
||||
/* MD4Update(MDp,X,count)
|
||||
** Input: X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use.
|
||||
** (if not a multiple of 8, uses high bits of last byte.)
|
||||
** Update MDp using the number of bits of X given by count.
|
||||
** This is the basic input routine for an MD4 user.
|
||||
** The routine completes the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MD4Update with a
|
||||
** count less than 512. A call with count 0 will be ignored if the
|
||||
** MD has already been terminated (done != 0), so an extra call with
|
||||
** count 0 can be given as a "courtesy close" to force termination
|
||||
** if desired.
|
||||
*/
|
||||
void
|
||||
MD4Update(MDp,X,count)
|
||||
MD4_CTX *MDp;
|
||||
unsigned char *X;
|
||||
unsigned int count;
|
||||
{
|
||||
unsigned int i, tmp, bit, byte, mask;
|
||||
unsigned char XX[64];
|
||||
unsigned char *p;
|
||||
|
||||
/* return with no error if this is a courtesy close with count
|
||||
** zero and MDp->done is true.
|
||||
*/
|
||||
if (count == 0 && MDp->done) return;
|
||||
/* check to see if MD is already done and report error */
|
||||
if (MDp->done)
|
||||
{ printf("\nError: MD4Update MD already done."); return; }
|
||||
|
||||
/* Add count to MDp->count */
|
||||
tmp = count;
|
||||
p = MDp->count;
|
||||
while (tmp)
|
||||
{ tmp += *p;
|
||||
*p++ = tmp;
|
||||
tmp = tmp >> 8;
|
||||
}
|
||||
|
||||
/* Process data */
|
||||
if (count == 512)
|
||||
{ /* Full block of data to handle */
|
||||
MDblock(MDp,X);
|
||||
}
|
||||
else if (count > 512) /* Check for count too large */
|
||||
{
|
||||
printf("\nError: MD4Update called with illegal count value %d.",
|
||||
count);
|
||||
return;
|
||||
}
|
||||
else /* partial block -- must be last block so finish up */
|
||||
{
|
||||
/* Find out how many bytes and residual bits there are */
|
||||
byte = count >> 3;
|
||||
bit = count & 7;
|
||||
/* Copy X into XX since we need to modify it */
|
||||
for (i=0;i<=byte;i++) XX[i] = X[i];
|
||||
for (i=byte+1;i<64;i++) XX[i] = 0;
|
||||
/* Add padding '1' bit and low-order zeros in last byte */
|
||||
mask = 1 << (7 - bit);
|
||||
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
|
||||
/* If room for bit count, finish up with this block */
|
||||
if (byte <= 55)
|
||||
{
|
||||
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,XX);
|
||||
}
|
||||
else /* need to do two blocks to finish up */
|
||||
{
|
||||
MDblock(MDp,XX);
|
||||
for (i=0;i<56;i++) XX[i] = 0;
|
||||
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,XX);
|
||||
}
|
||||
/* Set flag saying we're done with MD computation */
|
||||
MDp->done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Finish up MD4 computation and return message digest.
|
||||
*/
|
||||
void
|
||||
MD4Final(buf, MD)
|
||||
unsigned char *buf;
|
||||
MD4_CTX *MD;
|
||||
{
|
||||
int i, j;
|
||||
unsigned int w;
|
||||
|
||||
MD4Update(MD, NULL, 0);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
w = MD->buffer[i];
|
||||
for (j = 0; j < 4; ++j) {
|
||||
*buf++ = w;
|
||||
w >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** End of md4.c
|
||||
****************************(cut)***********************************/
|
||||
64
c/src/libnetworking/pppd/md4.h
Normal file
64
c/src/libnetworking/pppd/md4.h
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
/*
|
||||
** ********************************************************************
|
||||
** md4.h -- Header file for implementation of **
|
||||
** MD4 Message Digest Algorithm **
|
||||
** Updated: 2/13/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __P
|
||||
# if defined(__STDC__) || defined(__GNUC__)
|
||||
# define __P(x) x
|
||||
# else
|
||||
# define __P(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* MDstruct is the data structure for a message digest computation.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int buffer[4]; /* Holds 4-word result of MD computation */
|
||||
unsigned char count[8]; /* Number of bits processed so far */
|
||||
unsigned int done; /* Nonzero means MD computation finished */
|
||||
} MD4_CTX;
|
||||
|
||||
/* MD4Init(MD4_CTX *)
|
||||
** Initialize the MD4_CTX prepatory to doing a message digest
|
||||
** computation.
|
||||
*/
|
||||
extern void MD4Init __P((MD4_CTX *MD));
|
||||
|
||||
/* MD4Update(MD,X,count)
|
||||
** Input: X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use (an unsigned int).
|
||||
** Updates MD using the first "count" bits of X.
|
||||
** The array pointed to by X is not modified.
|
||||
** If count is not a multiple of 8, MD4Update uses high bits of
|
||||
** last byte.
|
||||
** This is the basic input routine for a user.
|
||||
** The routine terminates the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MD4Update with a
|
||||
** count less than 512. Zero is OK for a count.
|
||||
*/
|
||||
extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count));
|
||||
|
||||
/* MD4Print(MD)
|
||||
** Prints message digest buffer MD as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte
|
||||
** of buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
*/
|
||||
extern void MD4Print __P((MD4_CTX *));
|
||||
|
||||
/* MD4Final(buf, MD)
|
||||
** Returns message digest from MD and terminates the message
|
||||
** digest computation.
|
||||
*/
|
||||
extern void MD4Final __P((unsigned char *, MD4_CTX *));
|
||||
|
||||
/*
|
||||
** End of md4.h
|
||||
****************************(cut)***********************************/
|
||||
306
c/src/libnetworking/pppd/md5.c
Normal file
306
c/src/libnetworking/pppd/md5.c
Normal file
@@ -0,0 +1,306 @@
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** md5.c -- the source code for MD5 routines **
|
||||
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Message-digest routines: **
|
||||
** To form the message digest for a message M **
|
||||
** (1) Initialize a context buffer mdContext using MD5Init **
|
||||
** (2) Call MD5Update on mdContext and M **
|
||||
** (3) Call MD5Final on mdContext **
|
||||
** The message digest is now in mdContext->digest[0...15] **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/* forward declaration */
|
||||
static void Transform ();
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
#define UL(x) x##U
|
||||
#else
|
||||
#define UL(x) x
|
||||
#endif
|
||||
|
||||
/* The routine MD5Init initializes the message-digest context
|
||||
mdContext. All fields are set to zero.
|
||||
*/
|
||||
void MD5Init (mdContext)
|
||||
MD5_CTX *mdContext;
|
||||
{
|
||||
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
|
||||
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
mdContext->buf[0] = (UINT4)0x67452301;
|
||||
mdContext->buf[1] = (UINT4)0xefcdab89;
|
||||
mdContext->buf[2] = (UINT4)0x98badcfe;
|
||||
mdContext->buf[3] = (UINT4)0x10325476;
|
||||
}
|
||||
|
||||
/* The routine MD5Update updates the message-digest context to
|
||||
account for the presence of each of the characters inBuf[0..inLen-1]
|
||||
in the message whose digest is being computed.
|
||||
*/
|
||||
void MD5Update (mdContext, inBuf, inLen)
|
||||
MD5_CTX *mdContext;
|
||||
unsigned char *inBuf;
|
||||
unsigned int inLen;
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* update number of bits */
|
||||
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
|
||||
mdContext->i[1]++;
|
||||
mdContext->i[0] += ((UINT4)inLen << 3);
|
||||
mdContext->i[1] += ((UINT4)inLen >> 29);
|
||||
|
||||
while (inLen--) {
|
||||
/* add new character to buffer, increment mdi */
|
||||
mdContext->in[mdi++] = *inBuf++;
|
||||
|
||||
/* transform if necessary */
|
||||
if (mdi == 0x40) {
|
||||
for (i = 0, ii = 0; i < 16; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
mdi = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The routine MD5Final terminates the message-digest computation and
|
||||
ends with the desired message digest in mdContext->digest[0...15].
|
||||
*/
|
||||
void MD5Final (hash, mdContext)
|
||||
unsigned char hash[];
|
||||
MD5_CTX *mdContext;
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
unsigned int padLen;
|
||||
|
||||
/* save number of bits */
|
||||
in[14] = mdContext->i[0];
|
||||
in[15] = mdContext->i[1];
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* pad out to 56 mod 64 */
|
||||
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
|
||||
MD5Update (mdContext, PADDING, padLen);
|
||||
|
||||
/* append length in bits and transform */
|
||||
for (i = 0, ii = 0; i < 14; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
|
||||
/* store buffer in digest */
|
||||
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
|
||||
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
|
||||
mdContext->digest[ii+1] =
|
||||
(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
|
||||
mdContext->digest[ii+2] =
|
||||
(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
|
||||
mdContext->digest[ii+3] =
|
||||
(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
memcpy(hash, mdContext->digest, 16);
|
||||
}
|
||||
|
||||
/* Basic MD5 step. Transforms buf based on in.
|
||||
*/
|
||||
static void Transform (buf, in)
|
||||
UINT4 *buf;
|
||||
UINT4 *in;
|
||||
{
|
||||
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
|
||||
|
||||
/* Round 1 */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
|
||||
FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
|
||||
FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
|
||||
FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
|
||||
FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
|
||||
FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
|
||||
FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
|
||||
FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
|
||||
FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
|
||||
FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
|
||||
FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
|
||||
FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
|
||||
FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
|
||||
FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
|
||||
FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
|
||||
FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
|
||||
GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
|
||||
GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
|
||||
GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
|
||||
GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
|
||||
GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */
|
||||
GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
|
||||
GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
|
||||
GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
|
||||
GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
|
||||
GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
|
||||
GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
|
||||
GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
|
||||
GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
|
||||
GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
|
||||
GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
|
||||
HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
|
||||
HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
|
||||
HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
|
||||
HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
|
||||
HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
|
||||
HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
|
||||
HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
|
||||
HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
|
||||
HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
|
||||
HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
|
||||
HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */
|
||||
HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
|
||||
HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
|
||||
HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
|
||||
HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
|
||||
II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
|
||||
II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
|
||||
II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
|
||||
II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
|
||||
II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
|
||||
II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
|
||||
II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
|
||||
II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
|
||||
II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
|
||||
II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
|
||||
II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
|
||||
II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
|
||||
II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
|
||||
II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
|
||||
II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** End of md5.c **
|
||||
******************************** (cut) ********************************
|
||||
*/
|
||||
58
c/src/libnetworking/pppd/md5.h
Normal file
58
c/src/libnetworking/pppd/md5.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
***********************************************************************
|
||||
** md5.h -- header file for implementation of MD5 **
|
||||
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
|
||||
** Revised (for MD5): RLR 4/27/91 **
|
||||
** -- G modified to have y&~z instead of y&z **
|
||||
** -- FF, GG, HH modified to add in last register done **
|
||||
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
|
||||
** -- distinct additive constant for each step **
|
||||
** -- round 4 added, working mod 7 **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __MD5_INCLUDE__
|
||||
|
||||
/* typedef a 32-bit type */
|
||||
typedef unsigned int UINT4;
|
||||
|
||||
/* Data structure for MD5 (Message-Digest) computation */
|
||||
typedef struct {
|
||||
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
|
||||
UINT4 buf[4]; /* scratch buffer */
|
||||
unsigned char in[64]; /* input buffer */
|
||||
unsigned char digest[16]; /* actual digest after MD5Final call */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init ();
|
||||
void MD5Update ();
|
||||
void MD5Final ();
|
||||
|
||||
#define __MD5_INCLUDE__
|
||||
#endif /* __MD5_INCLUDE__ */
|
||||
393
c/src/libnetworking/pppd/options.c
Normal file
393
c/src/libnetworking/pppd/options.c
Normal file
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* options.c - handles option processing for PPP.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
/* #include <stdlib.h> */
|
||||
#include <termios.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef PPP_FILTER
|
||||
#include <pcap.h>
|
||||
#include <pcap-int.h> /* XXX: To get struct pcap */
|
||||
#endif
|
||||
|
||||
#include "pppd.h"
|
||||
#include "pathnames.h"
|
||||
#include "patchlevel.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ipcp.h"
|
||||
#include "upap.h"
|
||||
#include "chap.h"
|
||||
#include "ccp.h"
|
||||
#ifdef CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
|
||||
#ifdef IPX_CHANGE
|
||||
#include "ipxcp.h"
|
||||
#endif /* IPX_CHANGE */
|
||||
|
||||
#include <net/ppp-comp.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
|
||||
#ifndef GIDSET_TYPE
|
||||
#define GIDSET_TYPE gid_t
|
||||
#endif
|
||||
#if 0
|
||||
static int privileged_option; /* set iff the current option came from root */
|
||||
static char *option_source; /* string saying where the option came from */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Option variables and default values.
|
||||
*/
|
||||
#ifdef PPP_FILTER
|
||||
int dflag = 0; /* Tell libpcap we want debugging */
|
||||
#endif
|
||||
int debug = 1; /* Debug flag */
|
||||
int kdebugflag = 1; /* Tell kernel to print debug messages */
|
||||
int default_device = 1; /* Using /dev/tty or equivalent */
|
||||
char devnam[MAXPATHLEN] = "/dev/sccppp"; /* Device name */
|
||||
int crtscts = 0; /* Use hardware flow control */
|
||||
int modem = 0; /* Use modem control lines */
|
||||
int inspeed = B115200; /* Input/Output speed requested */
|
||||
u_int32_t netmask = 0; /* IP netmask to set on interface */
|
||||
int lockflag = 0; /* Create lock file to lock the serial dev */
|
||||
int nodetach = 0; /* Don't detach from controlling tty */
|
||||
char *connector[]={"TIMEOUT","3","ABORT","\nBUSY\r","ABORT","\nNO DIALTONE\r","ABORT","\nNO CARRIER\r","ABORT","\nNO ANSWER\r","ABORT","\nRINGING\r\n\r\nRINGING\r",
|
||||
"","\rAT","OK-+++\\c-OK","ATH0","TIMEOUT","30","OK","ATDT13","CONNECT",""};
|
||||
/*char *connector[]={"TIMEOUT","3","ABORT","\nBUSY\r","ABORT","\nNO DIALTONE\r","ABORT","\nNO CARRIER\r","ABORT","\nNO ANSWER\r","ABORT","\nRINGING\r\n\r\nRINGING\r",
|
||||
"","\rAT","OK-+++\\c-OK","ATH0","TIMEOUT","30","OK","ATDT0202122","CONNECT","","ppp","","Username:","ppp","Password:","ppp"};
|
||||
*/
|
||||
char *disconnector []; /* Script to disestablish physical link */
|
||||
char *welcomer []; /* Script to run after phys link estab. */
|
||||
int maxconnect = 0; /* Maximum connect time */
|
||||
char user[MAXNAMELEN]="stb"; /* Username for PAP */
|
||||
char passwd[MAXSECRETLEN]="stb"; /* Password for PAP */
|
||||
int auth_required = 0; /* Peer is required to authenticate */
|
||||
int defaultroute = 1; /* assign default route through interface */
|
||||
int proxyarp = 0; /* Set up proxy ARP entry for peer */
|
||||
int persist = 1; /* Reopen link after it goes down */
|
||||
int uselogin = 0; /* Use /etc/passwd for checking PAP */
|
||||
int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
|
||||
int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
|
||||
char our_name[MAXNAMELEN]="infotel"; /* Our name for authentication purposes */
|
||||
char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
|
||||
int explicit_remote = 0; /* User specified explicit remote name */
|
||||
int usehostname = 0; /* Use hostname for our_name */
|
||||
int disable_defaultip = 1; /* Don't use hostname for default IP adrs */
|
||||
int demand = 0; /* do dial-on-demand */
|
||||
char *ipparam = NULL; /* Extra parameter for ip up/down scripts */
|
||||
int cryptpap; /* Passwords in pap-secrets are encrypted */
|
||||
int idle_time_limit = 0; /* Disconnect if idle for this many seconds */
|
||||
int holdoff = 30; /* # seconds to pause before reconnecting */
|
||||
int refuse_pap = 0; /* Set to say we won't do PAP */
|
||||
int refuse_chap = 1; /* Set to say we won't do CHAP */
|
||||
|
||||
#ifdef MSLANMAN
|
||||
int ms_lanman = 0; /* Nonzero if use LanMan password instead of NT */
|
||||
/* Has meaning only with MS-CHAP challenges */
|
||||
#endif
|
||||
|
||||
struct option_info auth_req_info;
|
||||
struct option_info connector_info;
|
||||
struct option_info disconnector_info;
|
||||
struct option_info welcomer_info;
|
||||
struct option_info devnam_info;
|
||||
#ifdef PPP_FILTER
|
||||
struct bpf_program pass_filter;/* Filter program for packets to pass */
|
||||
struct bpf_program active_filter; /* Filter program for link-active pkts */
|
||||
pcap_t pc; /* Fake struct pcap so we can compile expr */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
#if 0
|
||||
static int setdevname __P((char *, int));
|
||||
static int setipaddr __P((char *));
|
||||
static int setspeed __P((char *));
|
||||
static int setdebug __P((char **));
|
||||
static int setkdebug __P((char **));
|
||||
static int setpassive __P((char **));
|
||||
static int setsilent __P((char **));
|
||||
static int noopt __P((char **));
|
||||
static int setnovj __P((char **));
|
||||
static int setnovjccomp __P((char **));
|
||||
static int setvjslots __P((char **));
|
||||
static int reqpap __P((char **));
|
||||
static int nopap __P((char **));
|
||||
#ifdef OLD_OPTIONS
|
||||
static int setupapfile __P((char **));
|
||||
#endif
|
||||
static int nochap __P((char **));
|
||||
static int reqchap __P((char **));
|
||||
static int noaccomp __P((char **));
|
||||
static int noasyncmap __P((char **));
|
||||
static int noip __P((char **));
|
||||
static int nomagicnumber __P((char **));
|
||||
static int setasyncmap __P((char **));
|
||||
static int setescape __P((char **));
|
||||
static int setmru __P((char **));
|
||||
static int setmtu __P((char **));
|
||||
#ifdef CBCP_SUPPORT
|
||||
static int setcbcp __P((char **));
|
||||
#endif
|
||||
static int nomru __P((char **));
|
||||
static int nopcomp __P((char **));
|
||||
static int setconnector __P((char **));
|
||||
static int setdisconnector __P((char **));
|
||||
static int setwelcomer __P((char **));
|
||||
static int setmaxconnect __P((char **));
|
||||
static int setdomain __P((char **));
|
||||
static int setnetmask __P((char **));
|
||||
static int setcrtscts __P((char **));
|
||||
static int setnocrtscts __P((char **));
|
||||
static int setxonxoff __P((char **));
|
||||
static int setnodetach __P((char **));
|
||||
static int setupdetach __P((char **));
|
||||
static int setmodem __P((char **));
|
||||
static int setlocal __P((char **));
|
||||
static int setlock __P((char **));
|
||||
static int setname __P((char **));
|
||||
static int setuser __P((char **));
|
||||
static int setremote __P((char **));
|
||||
static int setauth __P((char **));
|
||||
static int setnoauth __P((char **));
|
||||
static int readfile __P((char **));
|
||||
static int callfile __P((char **));
|
||||
static int setdefaultroute __P((char **));
|
||||
static int setnodefaultroute __P((char **));
|
||||
static int setproxyarp __P((char **));
|
||||
static int setnoproxyarp __P((char **));
|
||||
static int setpersist __P((char **));
|
||||
static int setnopersist __P((char **));
|
||||
static int setdologin __P((char **));
|
||||
static int setusehostname __P((char **));
|
||||
static int setnoipdflt __P((char **));
|
||||
static int setlcptimeout __P((char **));
|
||||
static int setlcpterm __P((char **));
|
||||
static int setlcpconf __P((char **));
|
||||
static int setlcpfails __P((char **));
|
||||
static int setipcptimeout __P((char **));
|
||||
static int setipcpterm __P((char **));
|
||||
static int setipcpconf __P((char **));
|
||||
static int setipcpfails __P((char **));
|
||||
static int setpaptimeout __P((char **));
|
||||
static int setpapreqs __P((char **));
|
||||
static int setpapreqtime __P((char **));
|
||||
static int setchaptimeout __P((char **));
|
||||
static int setchapchal __P((char **));
|
||||
static int setchapintv __P((char **));
|
||||
static int setipcpaccl __P((char **));
|
||||
static int setipcpaccr __P((char **));
|
||||
static int setlcpechointv __P((char **));
|
||||
static int setlcpechofails __P((char **));
|
||||
static int noccp __P((char **));
|
||||
static int setbsdcomp __P((char **));
|
||||
static int setnobsdcomp __P((char **));
|
||||
static int setdeflate __P((char **));
|
||||
static int setnodeflate __P((char **));
|
||||
static int setnodeflatedraft __P((char **));
|
||||
static int setdemand __P((char **));
|
||||
static int setpred1comp __P((char **));
|
||||
static int setnopred1comp __P((char **));
|
||||
static int setipparam __P((char **));
|
||||
static int setpapcrypt __P((char **));
|
||||
static int setidle __P((char **));
|
||||
static int setholdoff __P((char **));
|
||||
static int setdnsaddr __P((char **));
|
||||
static int resetipxproto __P((char **));
|
||||
static int setwinsaddr __P((char **));
|
||||
static int showversion __P((char **));
|
||||
static int showhelp __P((char **));
|
||||
|
||||
#ifdef PPP_FILTER
|
||||
static int setpdebug __P((char **));
|
||||
static int setpassfilter __P((char **));
|
||||
static int setactivefilter __P((char **));
|
||||
#endif
|
||||
|
||||
#ifdef IPX_CHANGE
|
||||
static int setipxproto __P((char **));
|
||||
static int setipxanet __P((char **));
|
||||
static int setipxalcl __P((char **));
|
||||
static int setipxarmt __P((char **));
|
||||
static int setipxnetwork __P((char **));
|
||||
static int setipxnode __P((char **));
|
||||
static int setipxrouter __P((char **));
|
||||
static int setipxname __P((char **));
|
||||
static int setipxcptimeout __P((char **));
|
||||
static int setipxcpterm __P((char **));
|
||||
static int setipxcpconf __P((char **));
|
||||
static int setipxcpfails __P((char **));
|
||||
#endif /* IPX_CHANGE */
|
||||
|
||||
#ifdef MSLANMAN
|
||||
static int setmslanman __P((char **));
|
||||
#endif
|
||||
|
||||
static int number_option __P((char *, u_int32_t *, int));
|
||||
static int int_option __P((char *, int *));
|
||||
static int readable __P((int fd));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Valid arguments.
|
||||
*/
|
||||
|
||||
/*
|
||||
* parse_args - parse a string of arguments from the command line.
|
||||
*/
|
||||
int
|
||||
parse_args(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* scan_args - scan the command line arguments to get the tty name,
|
||||
* if specified.
|
||||
*/
|
||||
|
||||
/*
|
||||
* usage - print out a message telling how to use the program.
|
||||
*/
|
||||
void
|
||||
usage()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* showhelp - print out usage message and exit.
|
||||
*/
|
||||
static int
|
||||
showhelp(argv)
|
||||
char **argv;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* showversion - print out the version number and exit.
|
||||
*/
|
||||
static int
|
||||
showversion(argv)
|
||||
char **argv;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
option_error __V((char *fmt, ...))
|
||||
{
|
||||
}
|
||||
/*
|
||||
* readable - check if a file is readable by the real user.
|
||||
*/
|
||||
/*static int
|
||||
readable(fd)
|
||||
int fd;
|
||||
{
|
||||
uid_t uid;
|
||||
int ngroups, i;
|
||||
struct stat sbuf;
|
||||
GIDSET_TYPE groups[NGROUPS_MAX];
|
||||
|
||||
uid = getuid();
|
||||
if (uid == 0)
|
||||
return 1;
|
||||
if (fstat(fd, &sbuf) != 0)
|
||||
return 0;
|
||||
if (sbuf.st_uid == uid)
|
||||
return sbuf.st_mode & S_IRUSR;
|
||||
if (sbuf.st_gid == getgid())
|
||||
return sbuf.st_mode & S_IRGRP;
|
||||
ngroups = getgroups(NGROUPS_MAX, groups);
|
||||
for (i = 0; i < ngroups; ++i)
|
||||
if (sbuf.st_gid == groups[i])
|
||||
return sbuf.st_mode & S_IRGRP;
|
||||
return sbuf.st_mode & S_IROTH;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* Read a word from a file.
|
||||
* Words are delimited by white-space or by quotes (" or ').
|
||||
* Quotes, white-space and \ may be escaped with \.
|
||||
* \<newline> is ignored.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following procedures parse options.
|
||||
*/
|
||||
|
||||
/*
|
||||
* readfile - take commands from a file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* callfile - take commands from /etc/ppp/peers/<name>.
|
||||
* Name may not contain /../, start with / or ../, or end in /..
|
||||
*/
|
||||
/*
|
||||
* setdebug - Set debug (command line argument).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* noopt - Disable all options.
|
||||
*/
|
||||
static int
|
||||
noopt(argv)
|
||||
char **argv;
|
||||
{
|
||||
BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
|
||||
BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
|
||||
BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options));
|
||||
BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options));
|
||||
|
||||
#ifdef IPX_CHANGE
|
||||
BZERO((char *) &ipxcp_wantoptions[0], sizeof (struct ipxcp_options));
|
||||
BZERO((char *) &ipxcp_allowoptions[0], sizeof (struct ipxcp_options));
|
||||
#endif /* IPX_CHANGE */
|
||||
|
||||
return (1);
|
||||
}
|
||||
6
c/src/libnetworking/pppd/patchlevel.h
Normal file
6
c/src/libnetworking/pppd/patchlevel.h
Normal file
@@ -0,0 +1,6 @@
|
||||
/* $Id$ */
|
||||
#define PATCHLEVEL 5
|
||||
|
||||
#define VERSION "2.3"
|
||||
#define IMPLEMENTATION ""
|
||||
#define DATE "4 May 1998"
|
||||
30
c/src/libnetworking/pppd/pathnames.h
Normal file
30
c/src/libnetworking/pppd/pathnames.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* define path names
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
|
||||
#else
|
||||
#define _PATH_VARRUN "/etc/ppp/"
|
||||
#define _PATH_DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
#define _PATH_UPAPFILE "/etc/ppp/pap-secrets"
|
||||
#define _PATH_CHAPFILE "/etc/ppp/chap-secrets"
|
||||
#define _PATH_SYSOPTIONS "/etc/ppp/options"
|
||||
#define _PATH_IPUP "/etc/ppp/ip-up"
|
||||
#define _PATH_IPDOWN "/etc/ppp/ip-down"
|
||||
#define _PATH_AUTHUP "/etc/ppp/auth-up"
|
||||
#define _PATH_AUTHDOWN "/etc/ppp/auth-down"
|
||||
#define _PATH_TTYOPT "/etc/ppp/options."
|
||||
#define _PATH_CONNERRS "/etc/ppp/connect-errors"
|
||||
#define _PATH_USEROPT ".ppprc"
|
||||
#define _PATH_PEERFILES "/etc/ppp/peers/"
|
||||
|
||||
#ifdef IPX_CHANGE
|
||||
#define _PATH_IPXUP "/etc/ppp/ipx-up"
|
||||
#define _PATH_IPXDOWN "/etc/ppp/ipx-down"
|
||||
#endif /* IPX_CHANGE */
|
||||
1080
c/src/libnetworking/pppd/ppp_tty.c
Normal file
1080
c/src/libnetworking/pppd/ppp_tty.c
Normal file
File diff suppressed because it is too large
Load Diff
497
c/src/libnetworking/pppd/pppd.h
Normal file
497
c/src/libnetworking/pppd/pppd.h
Normal file
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* pppd.h - PPP daemon global declarations.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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:
|
||||
*/
|
||||
|
||||
#ifndef __PPPD_H__
|
||||
#define __PPPD_H__
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
|
||||
#include <sys/types.h> /* for u_int32_t, if defined */
|
||||
#include <sys/time.h> /* for struct timeval */
|
||||
#include <net/ppp_defs.h>
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#define __V(x) x
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#define __V(x) (va_alist) va_dcl
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Limits.
|
||||
*/
|
||||
|
||||
#define NUM_PPP 1 /* One PPP interface supported (per process) */
|
||||
#define MAXWORDLEN 1024 /* max length of word in file (incl null) */
|
||||
#define MAXARGS 1 /* max # args to a command */
|
||||
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
|
||||
#define MAXSECRETLEN 256 /* max length of password or secret */
|
||||
|
||||
/*
|
||||
* Global variables.
|
||||
*/
|
||||
|
||||
extern int hungup; /* Physical layer has disconnected */
|
||||
extern int interfunit; /* Interface unit number */
|
||||
extern char ifname[]; /* Interface name */
|
||||
extern int ttyfd; /* Serial device file descriptor */
|
||||
extern char hostname[]; /* Our hostname */
|
||||
extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
|
||||
extern int phase; /* Current state of link - see values below */
|
||||
extern int baud_rate; /* Current link speed in bits/sec */
|
||||
extern char *progname; /* Name of this program */
|
||||
extern int redirect_stderr;/* Connector's stderr should go to file */
|
||||
extern char peer_authname[];/* Authenticated name of peer */
|
||||
extern int privileged; /* We were run by real-uid root */
|
||||
extern int need_holdoff; /* Need holdoff period after link terminates */
|
||||
extern char **script_env; /* Environment variables for scripts */
|
||||
extern int detached; /* Have detached from controlling tty */
|
||||
|
||||
/*
|
||||
* Variables set by command-line options.
|
||||
*/
|
||||
|
||||
extern int debug; /* Debug flag */
|
||||
extern int kdebugflag; /* Tell kernel to print debug messages */
|
||||
extern int default_device; /* Using /dev/tty or equivalent */
|
||||
extern char devnam[]; /* Device name */
|
||||
extern int crtscts; /* Use hardware flow control */
|
||||
extern int modem; /* Use modem control lines */
|
||||
extern int inspeed; /* Input/Output speed requested */
|
||||
extern u_int32_t netmask; /* IP netmask to set on interface */
|
||||
extern int lockflag; /* Create lock file to lock the serial dev */
|
||||
extern int nodetach; /* Don't detach from controlling tty */
|
||||
extern char *connector[]; /* Script to establish physical link */
|
||||
extern char *disconnector[]; /* Script to disestablish physical link */
|
||||
extern char *welcomer[]; /* Script to welcome client after connection */
|
||||
extern int maxconnect; /* Maximum connect time (seconds) */
|
||||
extern char user[]; /* Our name for authenticating ourselves */
|
||||
extern char passwd[]; /* Password for PAP */
|
||||
extern int auth_required; /* Peer is required to authenticate */
|
||||
extern int proxyarp; /* Set up proxy ARP entry for peer */
|
||||
extern int persist; /* Reopen link after it goes down */
|
||||
extern int uselogin; /* Use /etc/passwd for checking PAP */
|
||||
extern int lcp_echo_interval; /* Interval between LCP echo-requests */
|
||||
extern int lcp_echo_fails; /* Tolerance to unanswered echo-requests */
|
||||
extern char our_name[]; /* Our name for authentication purposes */
|
||||
extern char remote_name[]; /* Peer's name for authentication */
|
||||
extern int explicit_remote;/* remote_name specified with remotename opt */
|
||||
extern int usehostname; /* Use hostname for our_name */
|
||||
extern int disable_defaultip; /* Don't use hostname for default IP adrs */
|
||||
extern int demand; /* Do dial-on-demand */
|
||||
extern char *ipparam; /* Extra parameter for ip up/down scripts */
|
||||
extern int cryptpap; /* Others' PAP passwords are encrypted */
|
||||
extern int idle_time_limit;/* Shut down link if idle for this long */
|
||||
extern int holdoff; /* Dead time before restarting */
|
||||
extern int refuse_pap; /* Don't wanna auth. ourselves with PAP */
|
||||
extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */
|
||||
#ifdef PPP_FILTER
|
||||
extern struct bpf_program pass_filter; /* Filter for pkts to pass */
|
||||
extern struct bpf_program active_filter; /* Filter for link-active pkts */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MSLANMAN
|
||||
extern int ms_lanman; /* Nonzero if use LanMan password instead of NT */
|
||||
/* Has meaning only with MS-CHAP challenges */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Values for phase.
|
||||
*/
|
||||
#define PHASE_DEAD 0
|
||||
#define PHASE_INITIALIZE 1
|
||||
#define PHASE_DORMANT 2
|
||||
#define PHASE_ESTABLISH 3
|
||||
#define PHASE_AUTHENTICATE 4
|
||||
#define PHASE_CALLBACK 5
|
||||
#define PHASE_NETWORK 6
|
||||
#define PHASE_TERMINATE 7
|
||||
#define PHASE_HOLDOFF 8
|
||||
|
||||
/*
|
||||
* The following struct gives the addresses of procedures to call
|
||||
* for a particular protocol.
|
||||
*/
|
||||
struct protent {
|
||||
u_short protocol; /* PPP protocol number */
|
||||
/* Initialization procedure */
|
||||
void (*init) __P((int unit));
|
||||
/* Process a received packet */
|
||||
void (*input) __P((int unit, u_char *pkt, int len));
|
||||
/* Process a received protocol-reject */
|
||||
void (*protrej) __P((int unit));
|
||||
/* Lower layer has come up */
|
||||
void (*lowerup) __P((int unit));
|
||||
/* Lower layer has gone down */
|
||||
void (*lowerdown) __P((int unit));
|
||||
/* Open the protocol */
|
||||
void (*open) __P((int unit));
|
||||
/* Close the protocol */
|
||||
void (*close) __P((int unit, char *reason));
|
||||
/* Print a packet in readable form */
|
||||
int (*printpkt) __P((u_char *pkt, int len,
|
||||
void (*printer) __P((void *, char *, ...)),
|
||||
void *arg));
|
||||
/* Process a received data packet */
|
||||
void (*datainput) __P((int unit, u_char *pkt, int len));
|
||||
int enabled_flag; /* 0 iff protocol is disabled */
|
||||
char *name; /* Text name of protocol */
|
||||
/* Check requested options, assign defaults */
|
||||
void (*check_options) __P((void));
|
||||
/* Configure interface for demand-dial */
|
||||
int (*demand_conf) __P((int unit));
|
||||
/* Say whether to bring up link for this pkt */
|
||||
int (*active_pkt) __P((u_char *pkt, int len));
|
||||
};
|
||||
|
||||
/* Table of pointers to supported protocols */
|
||||
extern struct protent *protocols[];
|
||||
|
||||
/*
|
||||
* Prototypes.
|
||||
*/
|
||||
|
||||
/* Procedures exported from main.c. */
|
||||
void detach __P((void)); /* Detach from controlling tty */
|
||||
void die __P((int)); /* Cleanup and exit */
|
||||
void quit __P((void)); /* like die(1) */
|
||||
void novm __P((char *)); /* Say we ran out of memory, and die */
|
||||
void my_timeout __P((void (*func)(void *), void *arg, int t));
|
||||
/* Call func(arg) after t seconds */
|
||||
void untimeout __P((void (*func)(void *), void *arg));
|
||||
/* Cancel call to func(arg) */
|
||||
int run_program __P((char *prog, char **args, int must_exist));
|
||||
/* Run program prog with args in child */
|
||||
void demuxprotrej __P((int, int));
|
||||
/* Demultiplex a Protocol-Reject */
|
||||
void format_packet __P((u_char *, int, void (*) (void *, char *, ...),
|
||||
void *)); /* Format a packet in human-readable form */
|
||||
void log_packet __P((u_char *, int, char *, int));
|
||||
/* Format a packet and log it with syslog */
|
||||
void print_string __P((char *, int, void (*) (void *, char *, ...),
|
||||
void *)); /* Format a string for output */
|
||||
int fmtmsg __P((char *, int, char *, ...)); /* sprintf++ */
|
||||
int vfmtmsg __P((char *, int, char *, va_list)); /* vsprintf++ */
|
||||
void script_setenv __P((char *, char *)); /* set script env var */
|
||||
void script_unsetenv __P((char *)); /* unset script env var */
|
||||
/* My procedures */
|
||||
int connect_stb();
|
||||
int disconnect_stb();
|
||||
int pppdmain(int, char*[]);
|
||||
int chatmain(char*);
|
||||
|
||||
/* Procedures exported from auth.c */
|
||||
|
||||
void link_required __P((int)); /* we are starting to use the link */
|
||||
void link_terminated __P((int)); /* we are finished with the link */
|
||||
void link_down __P((int)); /* the LCP layer has left the Opened state */
|
||||
void link_established __P((int)); /* the link is up; authenticate now */
|
||||
void np_up __P((int, int)); /* a network protocol has come up */
|
||||
void np_down __P((int, int)); /* a network protocol has gone down */
|
||||
void np_finished __P((int, int)); /* a network protocol no longer needs link */
|
||||
void auth_peer_fail __P((int, int));
|
||||
/* peer failed to authenticate itself */
|
||||
void auth_peer_success __P((int, int, char *, int));
|
||||
/* peer successfully authenticated itself */
|
||||
void auth_withpeer_fail __P((int, int));
|
||||
/* we failed to authenticate ourselves */
|
||||
void auth_withpeer_success __P((int, int));
|
||||
/* we successfully authenticated ourselves */
|
||||
void auth_check_options __P((void));
|
||||
/* check authentication options supplied */
|
||||
void auth_reset __P((int)); /* check what secrets we have */
|
||||
int check_passwd __P((int, char *, int, char *, int, char **, int *));
|
||||
/* Check peer-supplied username/password */
|
||||
int get_secret __P((int, char *, char *, char *, int *, int));
|
||||
/* get "secret" for chap */
|
||||
int auth_ip_addr __P((int, u_int32_t));
|
||||
/* check if IP address is authorized */
|
||||
int bad_ip_adrs __P((u_int32_t));
|
||||
/* check if IP address is unreasonable */
|
||||
void check_access __P((FILE *, char *));
|
||||
/* check permissions on secrets file */
|
||||
|
||||
/* Procedures exported from demand.c */
|
||||
void demand_conf __P((void)); /* config interface(s) for demand-dial */
|
||||
void demand_block __P((void)); /* set all NPs to queue up packets */
|
||||
void demand_unblock __P((void)); /* set all NPs to pass packets */
|
||||
void demand_discard __P((void)); /* set all NPs to discard packets */
|
||||
void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
|
||||
int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
|
||||
int loop_frame __P((unsigned char *, int)); /* process frame from loopback */
|
||||
|
||||
/* Procedures exported from sys-*.c */
|
||||
void sys_init __P((void)); /* Do system-dependent initialization */
|
||||
void sys_cleanup __P((void)); /* Restore system state before exiting */
|
||||
void sys_check_options __P((void)); /* Check options specified */
|
||||
void sys_close __P((void)); /* Clean up in a child before execing */
|
||||
int ppp_available __P((void)); /* Test whether ppp kernel support exists */
|
||||
void open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
|
||||
void establish_ppp __P((int)); /* Turn serial port into a ppp interface */
|
||||
void restore_loop __P((void)); /* Transfer ppp unit back to loopback */
|
||||
void disestablish_ppp __P((int)); /* Restore port to normal operation */
|
||||
void clean_check __P((void)); /* Check if line was 8-bit clean */
|
||||
void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */
|
||||
void restore_tty __P((int)); /* Restore port's original parameters */
|
||||
void setdtr __P((int, int)); /* Raise or lower port's DTR line */
|
||||
void output __P((int, u_char *, int)); /* Output a PPP packet */
|
||||
void wait_input __P((struct timeval *));
|
||||
/* Wait for input, with timeout */
|
||||
void wait_loop_output __P((struct timeval *));
|
||||
/* Wait for pkt from loopback, with timeout */
|
||||
void wait_time __P((struct timeval *)); /* Wait for given length of time */
|
||||
int read_packet __P((u_char *)); /* Read PPP packet */
|
||||
int get_loop_output __P((void)); /* Read pkts from loopback */
|
||||
void ppp_send_config __P((int, int, u_int32_t, int, int));
|
||||
/* Configure i/f transmit parameters */
|
||||
void ppp_set_xaccm __P((int, ext_accm));
|
||||
/* Set extended transmit ACCM */
|
||||
void ppp_recv_config __P((int, int, u_int32_t, int, int));
|
||||
/* Configure i/f receive parameters */
|
||||
int ccp_test __P((int, u_char *, int, int));
|
||||
/* Test support for compression scheme */
|
||||
void ccp_flags_set __P((int, int, int));
|
||||
/* Set kernel CCP state */
|
||||
int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */
|
||||
int get_idle_time __P((int, struct ppp_idle *));
|
||||
/* Find out how long link has been idle */
|
||||
int sifvjcomp __P((int, int, int, int));
|
||||
/* Configure VJ TCP header compression */
|
||||
int sifup __P((int)); /* Configure i/f up (for IP) */
|
||||
int sifnpmode __P((int u, int proto, enum NPmode mode));
|
||||
/* Set mode for handling packets for proto */
|
||||
int sifdown __P((int)); /* Configure i/f down (for IP) */
|
||||
int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t));
|
||||
/* Configure IP addresses for i/f */
|
||||
int cifaddr __P((int, u_int32_t, u_int32_t));
|
||||
/* Reset i/f IP addresses */
|
||||
int sifdefaultroute __P((int, u_int32_t, u_int32_t));
|
||||
/* Create default route through i/f */
|
||||
int cifdefaultroute __P((int, u_int32_t, u_int32_t));
|
||||
/* Delete default route through i/f */
|
||||
int sifproxyarp __P((int, u_int32_t));
|
||||
/* Add proxy ARP entry for peer */
|
||||
int cifproxyarp __P((int, u_int32_t));
|
||||
/* Delete proxy ARP entry for peer */
|
||||
u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */
|
||||
int lock __P((char *)); /* Create lock file for device */
|
||||
void unlock __P((void)); /* Delete previously-created lock file */
|
||||
int daemon __P((int, int)); /* Detach us from terminal session */
|
||||
void logwtmp __P((const char *, const char *, const char *));
|
||||
/* Write entry to wtmp file */
|
||||
int get_host_seed __P((void)); /* Get host-dependent random number seed */
|
||||
#ifdef PPP_FILTER
|
||||
int set_filters __P((struct bpf_program *pass, struct bpf_program *active));
|
||||
/* Set filter programs in kernel */
|
||||
#endif
|
||||
|
||||
/* Procedures exported from options.c */
|
||||
int parse_args __P((int argc, char **argv));
|
||||
/* Parse options from arguments given */
|
||||
void usage __P((void)); /* Print a usage message */
|
||||
int options_from_file __P((char *filename, int must_exist, int check_prot,
|
||||
int privileged));
|
||||
/* Parse options from an options file */
|
||||
int options_from_user __P((void)); /* Parse options from user's .ppprc */
|
||||
int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
|
||||
void scan_args __P((int argc, char **argv));
|
||||
/* Look for tty name in command-line args */
|
||||
int getword __P((FILE *f, char *word, int *newlinep, char *filename));
|
||||
/* Read a word from a file */
|
||||
void option_error __P((char *fmt, ...));
|
||||
/* Print an error message about an option */
|
||||
|
||||
/*
|
||||
* This structure is used to store information about certain
|
||||
* options, such as where the option value came from (/etc/ppp/options,
|
||||
* command line, etc.) and whether it came from a privileged source.
|
||||
*/
|
||||
|
||||
struct option_info {
|
||||
int priv; /* was value set by sysadmin? */
|
||||
char *source; /* where option came from */
|
||||
};
|
||||
|
||||
extern struct option_info auth_req_info;
|
||||
extern struct option_info connector_info;
|
||||
extern struct option_info disconnector_info;
|
||||
extern struct option_info welcomer_info;
|
||||
extern struct option_info devnam_info;
|
||||
|
||||
/*
|
||||
* Inline versions of get/put char/short/long.
|
||||
* Pointer is advanced; we assume that both arguments
|
||||
* are lvalues and will already be in registers.
|
||||
* cp MUST be u_char *.
|
||||
*/
|
||||
#define GETCHAR(c, cp) { \
|
||||
(c) = *(cp)++; \
|
||||
}
|
||||
#define PUTCHAR(c, cp) { \
|
||||
*(cp)++ = (u_char) (c); \
|
||||
}
|
||||
|
||||
|
||||
#define GETSHORT(s, cp) { \
|
||||
(s) = *(cp)++ << 8; \
|
||||
(s) |= *(cp)++; \
|
||||
}
|
||||
#define PUTSHORT(s, cp) { \
|
||||
*(cp)++ = (u_char) ((s) >> 8); \
|
||||
*(cp)++ = (u_char) (s); \
|
||||
}
|
||||
|
||||
#define GETLONG(l, cp) { \
|
||||
(l) = *(cp)++ << 8; \
|
||||
(l) |= *(cp)++; (l) <<= 8; \
|
||||
(l) |= *(cp)++; (l) <<= 8; \
|
||||
(l) |= *(cp)++; \
|
||||
}
|
||||
#define PUTLONG(l, cp) { \
|
||||
*(cp)++ = (u_char) ((l) >> 24); \
|
||||
*(cp)++ = (u_char) ((l) >> 16); \
|
||||
*(cp)++ = (u_char) ((l) >> 8); \
|
||||
*(cp)++ = (u_char) (l); \
|
||||
}
|
||||
|
||||
#define INCPTR(n, cp) ((cp) += (n))
|
||||
#define DECPTR(n, cp) ((cp) -= (n))
|
||||
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
#undef TRUE
|
||||
#define TRUE 1
|
||||
|
||||
/*
|
||||
* System dependent definitions for user-level 4.3BSD UNIX implementation.
|
||||
*/
|
||||
|
||||
#define DEMUXPROTREJ(u, p) demuxprotrej(u, p)
|
||||
|
||||
#define TIMEOUT(r, f, t) my_timeout((r), (f), (t))
|
||||
#define UNTIMEOUT(r, f) untimeout((r), (f))
|
||||
|
||||
#define BCOPY(s, d, l) memcpy(d, s, l)
|
||||
#define BZERO(s, n) memset(s, 0, n)
|
||||
#define EXIT(u) quit()
|
||||
|
||||
#define PRINTMSG(m, l) { m[l] = '\0'; syslog(LOG_INFO, "Remote message: %s", m); }
|
||||
|
||||
/*
|
||||
* MAKEHEADER - Add Header fields to a packet.
|
||||
*/
|
||||
#define MAKEHEADER(p, t) { \
|
||||
PUTCHAR(PPP_ALLSTATIONS, p); \
|
||||
PUTCHAR(PPP_UI, p); \
|
||||
PUTSHORT(t, p); }
|
||||
|
||||
/* #define DEBUGALL */
|
||||
|
||||
#ifdef DEBUGALL
|
||||
#define DEBUGMAIN 1
|
||||
#define DEBUGFSM 1
|
||||
#define DEBUGLCP 1
|
||||
#define DEBUGIPCP 1
|
||||
#define DEBUGUPAP 1
|
||||
#define DEBUGCHAP 1
|
||||
#endif
|
||||
|
||||
#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */
|
||||
#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \
|
||||
|| defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \
|
||||
|| defined(DEBUGCHAP) || defined(DEBUG)
|
||||
#define LOG_PPP LOG_LOCAL2
|
||||
#else
|
||||
#define LOG_PPP LOG_DAEMON
|
||||
#endif
|
||||
#endif /* LOG_PPP */
|
||||
extern rtems_id pppdaemon_tid;
|
||||
#ifdef DEBUGMAIN
|
||||
#define MAINDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define MAINDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGSYS
|
||||
#define SYSDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define SYSDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFSM
|
||||
#define FSMDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define FSMDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGLCP
|
||||
#define LCPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define LCPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGIPCP
|
||||
#define IPCPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define IPCPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGUPAP
|
||||
#define UPAPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define UPAPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGCHAP
|
||||
#define CHAPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define CHAPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGIPXCP
|
||||
#define IPXCPDEBUG(x) if (debug) syslog x
|
||||
#else
|
||||
#define IPXCPDEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifndef SIGTYPE
|
||||
#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE)
|
||||
#define SIGTYPE void
|
||||
#else
|
||||
#define SIGTYPE int
|
||||
#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */
|
||||
#endif /* SIGTYPE */
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b)? (a): (b))
|
||||
#endif
|
||||
|
||||
#endif /* __PPP_H__ */
|
||||
1522
c/src/libnetworking/pppd/rtems-ppp.c
Normal file
1522
c/src/libnetworking/pppd/rtems-ppp.c
Normal file
File diff suppressed because it is too large
Load Diff
619
c/src/libnetworking/pppd/upap.c
Normal file
619
c/src/libnetworking/pppd/upap.c
Normal file
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* upap.c - User/Password Authentication Protocol.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* static char rcsid[] = "$Id$"; */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "upap.h"
|
||||
#define print_string(user, ulen, printer, arg)
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
static void upap_init __P((int));
|
||||
static void upap_lowerup __P((int));
|
||||
static void upap_lowerdown __P((int));
|
||||
static void upap_input __P((int, u_char *, int));
|
||||
static void upap_protrej __P((int));
|
||||
static int upap_printpkt __P((u_char *, int,
|
||||
void (*) __P((void *, char *, ...)), void *));
|
||||
|
||||
struct protent pap_protent = {
|
||||
PPP_PAP,
|
||||
upap_init,
|
||||
upap_input,
|
||||
upap_protrej,
|
||||
upap_lowerup,
|
||||
upap_lowerdown,
|
||||
NULL,
|
||||
NULL,
|
||||
upap_printpkt,
|
||||
NULL,
|
||||
1,
|
||||
"PAP",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
|
||||
|
||||
static void upap_timeout __P((void *));
|
||||
static void upap_reqtimeout __P((void *));
|
||||
static void upap_rauthreq __P((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthack __P((upap_state *, u_char *, int, int));
|
||||
static void upap_rauthnak __P((upap_state *, u_char *, int, int));
|
||||
static void upap_sauthreq __P((upap_state *));
|
||||
static void upap_sresp __P((upap_state *, int, int, char *, int));
|
||||
|
||||
|
||||
/*
|
||||
* upap_init - Initialize a UPAP unit.
|
||||
*/
|
||||
static void
|
||||
upap_init(unit)
|
||||
int unit;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
u->us_unit = unit;
|
||||
u->us_user = NULL;
|
||||
u->us_userlen = 0;
|
||||
u->us_passwd = NULL;
|
||||
u->us_passwdlen = 0;
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
u->us_id = 0;
|
||||
u->us_timeouttime = UPAP_DEFTIMEOUT;
|
||||
u->us_maxtransmits = 10;
|
||||
u->us_reqtimeout = UPAP_DEFREQTIME;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_authwithpeer - Authenticate us with our peer (start client).
|
||||
*
|
||||
* Set new state and send authenticate's.
|
||||
*/
|
||||
void
|
||||
upap_authwithpeer(unit, user, password)
|
||||
int unit;
|
||||
char *user, *password;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
/* Save the username and password we're given */
|
||||
u->us_user = user;
|
||||
u->us_userlen = strlen(user);
|
||||
u->us_passwd = password;
|
||||
u->us_passwdlen = strlen(password);
|
||||
u->us_transmits = 0;
|
||||
|
||||
/* Lower layer up yet? */
|
||||
if (u->us_clientstate == UPAPCS_INITIAL ||
|
||||
u->us_clientstate == UPAPCS_PENDING) {
|
||||
u->us_clientstate = UPAPCS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
upap_sauthreq(u); /* Start protocol */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_authpeer - Authenticate our peer (start server).
|
||||
*
|
||||
* Set new state.
|
||||
*/
|
||||
void
|
||||
upap_authpeer(unit)
|
||||
int unit;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
/* Lower layer up yet? */
|
||||
if (u->us_serverstate == UPAPSS_INITIAL ||
|
||||
u->us_serverstate == UPAPSS_PENDING) {
|
||||
u->us_serverstate = UPAPSS_PENDING;
|
||||
return;
|
||||
}
|
||||
|
||||
u->us_serverstate = UPAPSS_LISTEN;
|
||||
if (u->us_reqtimeout > 0)
|
||||
TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_timeout - Retransmission timer for sending auth-reqs expired.
|
||||
*/
|
||||
static void
|
||||
upap_timeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
upap_state *u = (upap_state *) arg;
|
||||
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ)
|
||||
return;
|
||||
|
||||
if (u->us_transmits >= u->us_maxtransmits) {
|
||||
/* give up in disgust */
|
||||
syslog(LOG_ERR, "No response to PAP authenticate-requests");
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
return;
|
||||
}
|
||||
|
||||
upap_sauthreq(u); /* Send Authenticate-Request */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_reqtimeout - Give up waiting for the peer to send an auth-req.
|
||||
*/
|
||||
static void
|
||||
upap_reqtimeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
upap_state *u = (upap_state *) arg;
|
||||
|
||||
if (u->us_serverstate != UPAPSS_LISTEN)
|
||||
return; /* huh?? */
|
||||
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
u->us_serverstate = UPAPSS_BADAUTH;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_lowerup - The lower layer is up.
|
||||
*
|
||||
* Start authenticating if pending.
|
||||
*/
|
||||
static void
|
||||
upap_lowerup(unit)
|
||||
int unit;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_INITIAL)
|
||||
u->us_clientstate = UPAPCS_CLOSED;
|
||||
else if (u->us_clientstate == UPAPCS_PENDING) {
|
||||
upap_sauthreq(u); /* send an auth-request */
|
||||
}
|
||||
|
||||
if (u->us_serverstate == UPAPSS_INITIAL)
|
||||
u->us_serverstate = UPAPSS_CLOSED;
|
||||
else if (u->us_serverstate == UPAPSS_PENDING) {
|
||||
u->us_serverstate = UPAPSS_LISTEN;
|
||||
if (u->us_reqtimeout > 0)
|
||||
TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_lowerdown - The lower layer is down.
|
||||
*
|
||||
* Cancel all timeouts.
|
||||
*/
|
||||
static void
|
||||
upap_lowerdown(unit)
|
||||
int unit;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */
|
||||
UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
|
||||
if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
|
||||
UNTIMEOUT(upap_reqtimeout, u);
|
||||
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_protrej - Peer doesn't speak this protocol.
|
||||
*
|
||||
* This shouldn't happen. In any case, pretend lower layer went down.
|
||||
*/
|
||||
static void
|
||||
upap_protrej(unit)
|
||||
int unit;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) {
|
||||
syslog(LOG_ERR, "PAP authentication failed due to protocol-reject");
|
||||
auth_withpeer_fail(unit, PPP_PAP);
|
||||
}
|
||||
if (u->us_serverstate == UPAPSS_LISTEN) {
|
||||
syslog(LOG_ERR, "PAP authentication of peer failed (protocol-reject)");
|
||||
auth_peer_fail(unit, PPP_PAP);
|
||||
}
|
||||
upap_lowerdown(unit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_input - Input UPAP packet.
|
||||
*/
|
||||
static void
|
||||
upap_input(unit, inpacket, l)
|
||||
int unit;
|
||||
u_char *inpacket;
|
||||
int l;
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
u_char *inp;
|
||||
u_char code, id;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Parse header (code, id and length).
|
||||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (l < UPAP_HEADERLEN) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < UPAP_HEADERLEN) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length."));
|
||||
return;
|
||||
}
|
||||
if (len > l) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
len -= UPAP_HEADERLEN;
|
||||
|
||||
/*
|
||||
* Action depends on code.
|
||||
*/
|
||||
switch (code) {
|
||||
case UPAP_AUTHREQ:
|
||||
upap_rauthreq(u, inp, id, len);
|
||||
break;
|
||||
|
||||
case UPAP_AUTHACK:
|
||||
upap_rauthack(u, inp, id, len);
|
||||
break;
|
||||
|
||||
case UPAP_AUTHNAK:
|
||||
upap_rauthnak(u, inp, id, len);
|
||||
break;
|
||||
|
||||
default: /* XXX Need code reject */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_rauth - Receive Authenticate.
|
||||
*/
|
||||
static void
|
||||
upap_rauthreq(u, inp, id, len)
|
||||
upap_state *u;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char ruserlen, rpasswdlen;
|
||||
char *ruser, *rpasswd;
|
||||
int retcode;
|
||||
char *msg;
|
||||
int msglen;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.", id));
|
||||
|
||||
if (u->us_serverstate < UPAPSS_LISTEN)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we receive a duplicate authenticate-request, we are
|
||||
* supposed to return the same status as for the first request.
|
||||
*/
|
||||
if (u->us_serverstate == UPAPSS_OPEN) {
|
||||
upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
|
||||
return;
|
||||
}
|
||||
if (u->us_serverstate == UPAPSS_BADAUTH) {
|
||||
upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse user/passwd.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(ruserlen, inp);
|
||||
len -= sizeof (u_char) + ruserlen + sizeof (u_char);
|
||||
if (len < 0) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
ruser = (char *) inp;
|
||||
INCPTR(ruserlen, inp);
|
||||
GETCHAR(rpasswdlen, inp);
|
||||
if (len < rpasswdlen) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
rpasswd = (char *) inp;
|
||||
|
||||
/*
|
||||
* Check the username and password given.
|
||||
*/
|
||||
retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
|
||||
rpasswdlen, &msg, &msglen);
|
||||
BZERO(rpasswd, rpasswdlen);
|
||||
|
||||
upap_sresp(u, retcode, id, msg, msglen);
|
||||
|
||||
if (retcode == UPAP_AUTHACK) {
|
||||
u->us_serverstate = UPAPSS_OPEN;
|
||||
auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
|
||||
} else {
|
||||
u->us_serverstate = UPAPSS_BADAUTH;
|
||||
auth_peer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
if (u->us_reqtimeout > 0)
|
||||
UNTIMEOUT(upap_reqtimeout, u);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_rauthack - Receive Authenticate-Ack.
|
||||
*/
|
||||
static void
|
||||
upap_rauthack(u, inp, id, len)
|
||||
upap_state *u;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char msglen;
|
||||
char *msg;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d.", id));
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Parse message.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(msglen, inp);
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
PRINTMSG(msg, msglen);
|
||||
|
||||
u->us_clientstate = UPAPCS_OPEN;
|
||||
|
||||
auth_withpeer_success(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_rauthnak - Receive Authenticate-Nakk.
|
||||
*/
|
||||
static void
|
||||
upap_rauthnak(u, inp, id, len)
|
||||
upap_state *u;
|
||||
u_char *inp;
|
||||
int id;
|
||||
int len;
|
||||
{
|
||||
u_char msglen;
|
||||
char *msg;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d.", id));
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Parse message.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
GETCHAR(msglen, inp);
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet."));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
PRINTMSG(msg, msglen);
|
||||
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
|
||||
syslog(LOG_ERR, "PAP authentication failed");
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_sauthreq - Send an Authenticate-Request.
|
||||
*/
|
||||
static void
|
||||
upap_sauthreq(u)
|
||||
upap_state *u;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) +
|
||||
u->us_userlen + u->us_passwdlen;
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_PAP);
|
||||
|
||||
PUTCHAR(UPAP_AUTHREQ, outp);
|
||||
PUTCHAR(++u->us_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
PUTCHAR(u->us_userlen, outp);
|
||||
BCOPY(u->us_user, outp, u->us_userlen);
|
||||
INCPTR(u->us_userlen, outp);
|
||||
PUTCHAR(u->us_passwdlen, outp);
|
||||
BCOPY(u->us_passwd, outp, u->us_passwdlen);
|
||||
|
||||
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d.", u->us_id));
|
||||
|
||||
TIMEOUT(upap_timeout, u, u->us_timeouttime);
|
||||
++u->us_transmits;
|
||||
u->us_clientstate = UPAPCS_AUTHREQ;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upap_sresp - Send a response (ack or nak).
|
||||
*/
|
||||
static void
|
||||
upap_sresp(u, code, id, msg, msglen)
|
||||
upap_state *u;
|
||||
u_char code, id;
|
||||
char *msg;
|
||||
int msglen;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
|
||||
outp = outpacket_buf;
|
||||
MAKEHEADER(outp, PPP_PAP);
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
PUTCHAR(msglen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d.", code, id));
|
||||
}
|
||||
|
||||
/*
|
||||
* upap_printpkt - print the contents of a PAP packet.
|
||||
*/
|
||||
static char *upap_codenames[] = {
|
||||
"AuthReq", "AuthAck", "AuthNak"
|
||||
};
|
||||
|
||||
static int
|
||||
upap_printpkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
int code, id, len;
|
||||
int mlen, ulen, wlen;
|
||||
char *user, *pwd, *msg;
|
||||
u_char *pstart;
|
||||
|
||||
if (plen < UPAP_HEADERLEN)
|
||||
return 0;
|
||||
pstart = p;
|
||||
GETCHAR(code, p);
|
||||
GETCHAR(id, p);
|
||||
GETSHORT(len, p);
|
||||
if (len < UPAP_HEADERLEN || len > plen)
|
||||
return 0;
|
||||
|
||||
if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *))
|
||||
printer(arg, " %s", upap_codenames[code-1]);
|
||||
else
|
||||
printer(arg, " code=0x%x", code);
|
||||
printer(arg, " id=0x%x", id);
|
||||
len -= UPAP_HEADERLEN;
|
||||
switch (code) {
|
||||
case UPAP_AUTHREQ:
|
||||
if (len < 1)
|
||||
break;
|
||||
ulen = p[0];
|
||||
if (len < ulen + 2)
|
||||
break;
|
||||
wlen = p[ulen + 1];
|
||||
if (len < ulen + wlen + 2)
|
||||
break;
|
||||
user = (char *) (p + 1);
|
||||
pwd = (char *) (p + ulen + 2);
|
||||
p += ulen + wlen + 2;
|
||||
len -= ulen + wlen + 2;
|
||||
printer(arg, " user=");
|
||||
print_string(user, ulen, printer, arg);
|
||||
printer(arg, " password=");
|
||||
print_string(pwd, wlen, printer, arg);
|
||||
break;
|
||||
case UPAP_AUTHACK:
|
||||
case UPAP_AUTHNAK:
|
||||
if (len < 1)
|
||||
break;
|
||||
mlen = p[0];
|
||||
if (len < mlen + 1)
|
||||
break;
|
||||
msg = (char *) (p + 1);
|
||||
p += mlen + 1;
|
||||
len -= mlen + 1;
|
||||
printer(arg, " ");
|
||||
print_string(msg, mlen, printer, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
/* print the rest of the bytes in the packet */
|
||||
for (; len > 0; --len) {
|
||||
GETCHAR(code, p);
|
||||
printer(arg, " %.2x", code);
|
||||
}
|
||||
|
||||
return p - pstart;
|
||||
}
|
||||
87
c/src/libnetworking/pppd/upap.h
Normal file
87
c/src/libnetworking/pppd/upap.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* upap.h - User/Password Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1989 Carnegie Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 Carnegie Mellon University. The name of the
|
||||
* University 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Packet header = Code, id, length.
|
||||
*/
|
||||
#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short))
|
||||
|
||||
|
||||
/*
|
||||
* UPAP codes.
|
||||
*/
|
||||
#define UPAP_AUTHREQ 1 /* Authenticate-Request */
|
||||
#define UPAP_AUTHACK 2 /* Authenticate-Ack */
|
||||
#define UPAP_AUTHNAK 3 /* Authenticate-Nak */
|
||||
|
||||
|
||||
/*
|
||||
* Each interface is described by upap structure.
|
||||
*/
|
||||
typedef struct upap_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
char *us_user; /* User */
|
||||
int us_userlen; /* User length */
|
||||
char *us_passwd; /* Password */
|
||||
int us_passwdlen; /* Password length */
|
||||
int us_clientstate; /* Client state */
|
||||
int us_serverstate; /* Server state */
|
||||
u_char us_id; /* Current id */
|
||||
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
|
||||
int us_transmits; /* Number of auth-reqs sent */
|
||||
int us_maxtransmits; /* Maximum number of auth-reqs to send */
|
||||
int us_reqtimeout; /* Time to wait for auth-req from peer */
|
||||
} upap_state;
|
||||
|
||||
|
||||
/*
|
||||
* Client states.
|
||||
*/
|
||||
#define UPAPCS_INITIAL 0 /* Connection down */
|
||||
#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */
|
||||
#define UPAPCS_PENDING 2 /* Connection down, have requested auth */
|
||||
#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */
|
||||
#define UPAPCS_OPEN 4 /* We've received an Ack */
|
||||
#define UPAPCS_BADAUTH 5 /* We've received a Nak */
|
||||
|
||||
/*
|
||||
* Server states.
|
||||
*/
|
||||
#define UPAPSS_INITIAL 0 /* Connection down */
|
||||
#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */
|
||||
#define UPAPSS_PENDING 2 /* Connection down, have requested auth */
|
||||
#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */
|
||||
#define UPAPSS_OPEN 4 /* We've sent an Ack */
|
||||
#define UPAPSS_BADAUTH 5 /* We've sent a Nak */
|
||||
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */
|
||||
#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */
|
||||
|
||||
extern upap_state upap[];
|
||||
|
||||
void upap_authwithpeer __P((int, char *, char *));
|
||||
void upap_authpeer __P((int));
|
||||
|
||||
extern struct protent pap_protent;
|
||||
@@ -174,9 +174,10 @@ CODE facilitynames[] = {
|
||||
#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
|
||||
#define LOG_PERROR 0x20 /* log to stderr as well */
|
||||
|
||||
/*
|
||||
#ifdef KERNEL
|
||||
|
||||
#else /* not KERNEL */
|
||||
#else not KERNEL */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdarg.h>
|
||||
@@ -189,6 +190,6 @@ void syslog __P((int, const char *, ...));
|
||||
void vsyslog __P((int, const char *, va_list));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !KERNEL */
|
||||
/* #endif !KERNEL */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@ PROJECT_ROOT = @PROJECT_ROOT@
|
||||
VPATH = @srcdir@
|
||||
|
||||
NET_O_PIECES = kern lib libc net netinet nfs rtems rtems_servers \
|
||||
$(POSIX_PIECES)
|
||||
pppd $(POSIX_PIECES)
|
||||
OBJS = $(foreach piece, $(NET_O_PIECES), ../$(piece)/$(ARCH)/*.o)
|
||||
LIB = $(ARCH)/libnetworking.a
|
||||
|
||||
|
||||
Reference in New Issue
Block a user