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

📄 ipcp.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * ipcp.c - PPP IP Control Protocol. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The name "Carnegie Mellon University" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For permission or any legal *    details, please contact *      Office of Technology Transfer *      Carnegie Mellon University *      5000 Forbes Avenue *      Pittsburgh, PA  15213-3890 *      (412) 268-4387, fax: (412) 268-7395 *      tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by Computing Services *     at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#define RCSID	"$Id: ipcp.c,v 1.70 2005/08/25 23:59:34 paulus Exp $"/* * TODO: */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <netdb.h>#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "pppd.h"#include "fsm.h"#include "ipcp.h"#include "pathnames.h"static const char rcsid[] = RCSID;/* global vars */ipcp_options ipcp_wantoptions[NUM_PPP];	/* Options that we want to request */ipcp_options ipcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ipcp_options ipcp_hisoptions[NUM_PPP];	/* Options that we ack'd */u_int32_t netmask = 0;		/* IP netmask to set on interface */bool	disable_defaultip = 0;	/* Don't use hostname for default IP adrs *//* Hook for a plugin to know when IP protocol has come up */void (*ip_up_hook) __P((void)) = NULL;/* Hook for a plugin to know when IP protocol has come down */void (*ip_down_hook) __P((void)) = NULL;/* Hook for a plugin to choose the remote IP address */void (*ip_choose_hook) __P((u_int32_t *)) = NULL;/* Notifiers for when IPCP goes up and down */struct notifier *ip_up_notifier = NULL;struct notifier *ip_down_notifier = NULL;/* local vars */static int default_route_set[NUM_PPP];	/* Have set up a default route */static int proxy_arp_set[NUM_PPP];	/* Have created proxy arp entry */static bool usepeerdns;			/* Ask peer for DNS addrs */static int ipcp_is_up;			/* have called np_up() */static int ipcp_is_open;		/* haven't called np_finished() */static bool ask_for_local;		/* request our address from peer */static char vj_value[8];		/* string form of vj option value */static char netmask_str[20];		/* string form of netmask value *//* * Callbacks for fsm code.  (CI = Configuration Information) */static void ipcp_resetci __P((fsm *));	/* Reset our CI */static int  ipcp_cilen __P((fsm *));	        /* Return length of our CI */static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */static int  ipcp_ackci __P((fsm *, u_char *, int));	/* Peer ack'd our CI */static int  ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */static int  ipcp_rejci __P((fsm *, u_char *, int));	/* Peer rej'd our CI */static int  ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */static void ipcp_up __P((fsm *));		/* We're UP */static void ipcp_down __P((fsm *));		/* We're DOWN */static void ipcp_finished __P((fsm *));	/* Don't need lower layer */fsm ipcp_fsm[NUM_PPP];		/* IPCP fsm structure */static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */    ipcp_resetci,		/* Reset our Configuration Information */    ipcp_cilen,			/* Length of our Configuration Information */    ipcp_addci,			/* Add our Configuration Information */    ipcp_ackci,			/* ACK our Configuration Information */    ipcp_nakci,			/* NAK our Configuration Information */    ipcp_rejci,			/* Reject our Configuration Information */    ipcp_reqci,			/* Request peer's Configuration Information */    ipcp_up,			/* Called when fsm reaches OPENED state */    ipcp_down,			/* Called when fsm leaves OPENED state */    NULL,			/* Called when we want the lower layer up */    ipcp_finished,		/* Called when we want the lower layer down */    NULL,			/* Called when Protocol-Reject received */    NULL,			/* Retransmission is necessary */    NULL,			/* Called to handle protocol-specific codes */    "IPCP"			/* String name of protocol */};/* * Command-line options. */static int setvjslots __P((char **));static int setdnsaddr __P((char **));static int setwinsaddr __P((char **));static int setnetmask __P((char **));int setipaddr __P((char *, char **, int));static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *));static option_t ipcp_option_list[] = {    { "noip", o_bool, &ipcp_protent.enabled_flag,      "Disable IP and IPCP" },    { "-ip", o_bool, &ipcp_protent.enabled_flag,      "Disable IP and IPCP", OPT_ALIAS },    { "novj", o_bool, &ipcp_wantoptions[0].neg_vj,      "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj },    { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj,      "Disable VJ compression", OPT_ALIAS | OPT_A2CLR,      &ipcp_allowoptions[0].neg_vj },    { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag,      "Disable VJ connection-ID compression", OPT_A2CLR,      &ipcp_allowoptions[0].cflag },    { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,      "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR,      &ipcp_allowoptions[0].cflag },    /*/{ "vj-max-slots", o_special, (void *)setvjslots,      "Set maximum VJ header slots",      OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value },*/    { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,      "Accept peer's address for us", 1 },    { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,      "Accept peer's address for it", 1 },    { "ipparam", o_string, &ipparam,      "Set ip script parameter", OPT_PRIO },    { "noipdefault", o_bool, &disable_defaultip,      "Don't use name for default IP adrs", 1 },    { "ms-dns", 1, (void *)setdnsaddr,      "DNS address for the peer's use" },    { "ms-wins", 1, (void *)setwinsaddr,      "Nameserver for SMB over TCP/IP for peer" },    { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,      "Set timeout for IPCP", OPT_PRIO },    { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,      "Set max #xmits for term-reqs", OPT_PRIO },    { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,      "Set max #xmits for conf-reqs", OPT_PRIO },    { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,      "Set max #conf-naks for IPCP", OPT_PRIO },    { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route,      "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },    { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,      "disable defaultroute option", OPT_A2CLR,      &ipcp_wantoptions[0].default_route },    { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,      "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,      &ipcp_wantoptions[0].default_route },    { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,      "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },    { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,      "disable proxyarp option", OPT_A2CLR,      &ipcp_wantoptions[0].proxy_arp },    { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,      "disable proxyarp option", OPT_ALIAS | OPT_A2CLR,      &ipcp_wantoptions[0].proxy_arp },    { "usepeerdns", o_bool, &usepeerdns,      "Ask peer for DNS address(es)", 1 },    { "netmask", o_special, (void *)setnetmask,      "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },    { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs,      "Disable old-style IP-Addresses usage", OPT_A2CLR,      &ipcp_allowoptions[0].old_addrs },    { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr,      "Disable IP-Address usage", OPT_A2CLR,      &ipcp_allowoptions[0].neg_addr },    { "IP addresses", o_wild, (void *) &setipaddr,      "set local and remote IP addresses",      OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr },    { NULL }};/* * Protocol entry points from main code. */static void ipcp_init __P((int));static void ipcp_open __P((int));static void ipcp_close __P((int, char *));static void ipcp_lowerup __P((int));static void ipcp_lowerdown __P((int));static void ipcp_input __P((int, u_char *, int));static void ipcp_protrej __P((int));static int  ipcp_printpkt __P((u_char *, int,			       void (*) __P((void *, char *, ...)), void *));static void ip_check_options __P((void));static int  ip_demand_conf __P((int));static int  ip_active_pkt __P((u_char *, int));static void create_resolv __P((u_int32_t, u_int32_t));struct protent ipcp_protent = {    PPP_IPCP,    ipcp_init,    ipcp_input,    ipcp_protrej,    ipcp_lowerup,    ipcp_lowerdown,    ipcp_open,    ipcp_close,    ipcp_printpkt,    NULL,    1,    "IPCP",    "IP",    ipcp_option_list,    ip_check_options,    ip_demand_conf,    ip_active_pkt};static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));static void ipcp_script __P((char *, int));	/* Run an up/down script */static void ipcp_script_done __P((void *));/* * Lengths of configuration options. */#define CILEN_VOID	2#define CILEN_COMPRESS	4	/* min length for compression protocol opt. */#define CILEN_VJ	6	/* length for RFC1332 Van-Jacobson opt. */#define CILEN_ADDR	6	/* new-style single address option */#define CILEN_ADDRS	10	/* old-style dual address option */#define CODENAME(x)	((x) == CONFACK ? "ACK" : \			 (x) == CONFNAK ? "NAK" : "REJ")/* * This state variable is used to ensure that we don't * run an ipcp-up/down script while one is already running. */static enum script_state {    s_down,    s_up,} ipcp_script_state;static pid_t ipcp_script_pid;/* * Make a string representation of a network IP address. */char *ip_ntoa(ipaddr)u_int32_t ipaddr;{    static char b[64];    slprintf(b, sizeof(b), "%I", ipaddr);    return b;}/* * Option parsing. */ #ifdef INCLUDE/* * setvjslots - set maximum number of connection slots for VJ compression */static intsetvjslots(argv)    char **argv;{    int value;    if (!int_option(*argv, &value))	return 0;    if (value < 2 || value > 16) {	option_error("vj-max-slots value must be between 2 and 16");	return 0;    }    ipcp_wantoptions [0].maxslotindex =        ipcp_allowoptions[0].maxslotindex = value - 1;    slprintf(vj_value, sizeof(vj_value), "%d", value);    return 1;}#endif /* INCLUDE *//* * setdnsaddr - set the dns address(es) */static intsetdnsaddr(argv)    char **argv;{    u_int32_t dns;    struct hostent *hp;    dns = inet_addr(*argv);    if (dns == (u_int32_t) -1) {	if ((hp = gethostbyname(*argv)) == NULL) {	    option_error("invalid address parameter '%s' for ms-dns option",			 *argv);	    return 0;	}	dns = *(u_int32_t *)hp->h_addr;    }    /* We take the last 2 values given, the 2nd-last as the primary       and the last as the secondary.  If only one is given it       becomes both primary and secondary. */    if (ipcp_allowoptions[0].dnsaddr[1] == 0)	ipcp_allowoptions[0].dnsaddr[0] = dns;    else	ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1];    /* always set the secondary address value. */    ipcp_allowoptions[0].dnsaddr[1] = dns;    return (1);}/* * setwinsaddr - set the wins address(es) * This is primrarly used with the Samba package under UNIX or for pointing * the caller to the existing WINS server on a Windows NT platform. */static intsetwinsaddr(argv)    char **argv;{    u_int32_t wins;    struct hostent *hp;    wins = inet_addr(*argv);    if (wins == (u_int32_t) -1) {	if ((hp = gethostbyname(*argv)) == NULL) {	    option_error("invalid address parameter '%s' for ms-wins option",			 *argv);	    return 0;	}	wins = *(u_int32_t *)hp->h_addr;    }    /* We take the last 2 values given, the 2nd-last as the primary       and the last as the secondary.  If only one is given it       becomes both primary and secondary. */    if (ipcp_allowoptions[0].winsaddr[1] == 0)	ipcp_allowoptions[0].winsaddr[0] = wins;    else	ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1];    /* always set the secondary address value. */    ipcp_allowoptions[0].winsaddr[1] = wins;    return (1);}/* * setipaddr - Set the IP address * If doit is 0, the call is to check whether this option is * potentially an IP address specification. * Not static so that plugins can call it to set the addresses */intsetipaddr(arg, argv, doit)    char *arg;    char **argv;    int doit;{    struct hostent *hp;    char *colon;    u_int32_t local, remote;    ipcp_options *wo = &ipcp_wantoptions[0];    static int prio_local = 0, prio_remote = 0;    /*     * IP address pair separated by ":".     */    if ((colon = strchr(arg, ':')) == NULL)	return 0;    if (!doit)	return 1;      /*     * If colon first character, then no local addr.     */    if (colon != arg && option_priority >= prio_local) {	*colon = '\0';	if ((local = inet_addr(arg)) == (u_int32_t) -1) {	    if ((hp = gethostbyname(arg)) == NULL) {		option_error("unknown host: %s", arg);		return 0;	    }	    local = *(u_int32_t *)hp->h_addr;	}	if (bad_ip_adrs(local)) {	    option_error("bad local IP address %s", ip_ntoa(local));	    return 0;	}	if (local != 0)	    wo->ouraddr = local;	*colon = ':';	prio_local = option_priority;    }      /*     * If colon last character, then no remote addr.     */    if (*++colon != '\0' && option_priority >= prio_remote) {	if ((remote = inet_addr(colon)) == (u_int32_t) -1) {	    if ((hp = gethostbyname(colon)) == NULL) {		option_error("unknown host: %s", colon);		return 0;	    }	    remote = *(u_int32_t *)hp->h_addr;	    if (remote_name[0] == 0)		strlcpy(remote_name, colon, sizeof(remote_name));	}	if (bad_ip_adrs(remote)) {	    option_error("bad remote IP address %s", ip_ntoa(remote));	    return 0;	}	if (remote != 0)	    wo->hisaddr = remote;	prio_remote = option_priority;    }    return 1;}static voidprintipaddr(opt, printer, arg)    option_t *opt;    void (*printer) __P((void *, char *, ...));    void *arg;{	ipcp_options *wo = &ipcp_wantoptions[0];	if (wo->ouraddr != 0)		printer(arg, "%I", wo->ouraddr);	printer(arg, ":");	if (wo->hisaddr != 0)		printer(arg, "%I", wo->hisaddr);}/* * setnetmask - set the netmask to be used on the interface. */static intsetnetmask(argv)    char **argv;{    u_int32_t mask;    int n;    char *p;    /*     * Unfortunately, if we use inet_addr, we can't tell whether     * a result of all 1s is an error or a valid 255.255.255.255.     */    p = *argv;    n = parse_dotted_ip(p, &mask);    mask = htonl(mask);    if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) {	option_error("invalid netmask value '%s'", *argv);	return 0;    }    netmask = mask;    slprintf(netmask_str, sizeof(netmask_str), "%I", mask);    return (1);}intparse_dotted_ip(p, vp)    char *p;    u_int32_t *vp;{    int n;    u_int32_t v, b;    char *endp, *p0 = p;    v = 0;    for (n = 3;; --n) {	b = strtoul(p, &endp, 0);	if (endp == p)	    return 0;	if (b > 255) {	    if (n < 3)		return 0;	    /* accept e.g. 0xffffff00 */	    *vp = b;	    return endp - p0;	}	v |= b << (n * 8);	p = endp;	if (n == 0)	    break;	if (*p != '.')	    return 0;	++p;    }    *vp = v;    return p - p0;

⌨️ 快捷键说明

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