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

📄 ipcp.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))	return 0;    ipcp_script(_PATH_IPPREUP, 1);    if (!sifup(u))	return 0;    if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))	return 0;    if (wo->default_route)	if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))	    default_route_set[u] = 1;    if (wo->proxy_arp)	if (sifproxyarp(u, wo->hisaddr))	    proxy_arp_set[u] = 1;    notice("local  IP address %I", wo->ouraddr);    notice("remote IP address %I", wo->hisaddr);    return 1;}/* * ipcp_up - IPCP has come UP. * * Configure the IP network interface appropriately and bring it up. */static voidipcp_up(f)    fsm *f;{    u_int32_t mask;    ipcp_options *ho = &ipcp_hisoptions[f->unit];    ipcp_options *go = &ipcp_gotoptions[f->unit];    ipcp_options *wo = &ipcp_wantoptions[f->unit];    IPCPDEBUG(("ipcp: up"));    /*     * We must have a non-zero IP address for both ends of the link.     */    if (!ho->neg_addr && !ho->old_addrs)	ho->hisaddr = wo->hisaddr;    if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs)	&& wo->ouraddr != 0) {	error("Peer refused to agree to our IP address");	ipcp_close(f->unit, "Refused our IP address");	return;    }    if (go->ouraddr == 0) {	error("Could not determine local IP address");	ipcp_close(f->unit, "Could not determine local IP address");	return;    }    if (ho->hisaddr == 0) {	ho->hisaddr = htonl(0x0a404040 + ifunit);	warn("Could not determine remote IP address: defaulting to %I",	     ho->hisaddr);    }    script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);    script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);    if (go->dnsaddr[0])	script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);    if (go->dnsaddr[1])	script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);    if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {	script_setenv("USEPEERDNS", "1", 0);	create_resolv(go->dnsaddr[0], go->dnsaddr[1]);    }    /*     * Check that the peer is allowed to use the IP address it wants.     */    if (!auth_ip_addr(f->unit, ho->hisaddr)) {	error("Peer is not authorized to use remote address %I", ho->hisaddr);	ipcp_close(f->unit, "Unauthorized remote IP address");	return;    }    /* set tcp compression */    sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);    /*     * If we are doing dial-on-demand, the interface is already     * configured, so we put out any saved-up packets, then set the     * interface to pass IP packets.     */    if (demand) {	if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {	    ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);	    if (go->ouraddr != wo->ouraddr) {		warn("Local IP address changed to %I", go->ouraddr);		script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);		wo->ouraddr = go->ouraddr;	    } else		script_unsetenv("OLDIPLOCAL");	    if (ho->hisaddr != wo->hisaddr) {		warn("Remote IP address changed to %I", ho->hisaddr);		script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);		wo->hisaddr = ho->hisaddr;	    } else		script_unsetenv("OLDIPREMOTE");	    /* Set the interface to the new addresses */	    mask = GetMask(go->ouraddr);	    if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {		if (debug)		    warn("Interface configuration failed");		ipcp_close(f->unit, "Interface configuration failed");		return;	    }	    /* assign a default route through the interface if required */	    if (ipcp_wantoptions[f->unit].default_route) 		if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))		    default_route_set[f->unit] = 1;	    /* Make a proxy ARP entry if requested. */	    if (ipcp_wantoptions[f->unit].proxy_arp)		if (sifproxyarp(f->unit, ho->hisaddr))		    proxy_arp_set[f->unit] = 1;	}	demand_rexmit(PPP_IP);	sifnpmode(f->unit, PPP_IP, NPMODE_PASS);    } else {	/*	 * Set IP addresses and (if specified) netmask.	 */	mask = GetMask(go->ouraddr);#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))	if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {	    if (debug)		warn("Interface configuration failed");	    ipcp_close(f->unit, "Interface configuration failed");	    return;	}#endif	/* run the pre-up script, if any, and wait for it to finish */	ipcp_script(_PATH_IPPREUP, 1);	/* bring the interface up for IP */	if (!sifup(f->unit)) {	    if (debug)		warn("Interface failed to come up");	    ipcp_close(f->unit, "Interface configuration failed");	    return;	}#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))	if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {	    if (debug)		warn("Interface configuration failed");	    ipcp_close(f->unit, "Interface configuration failed");	    return;	}#endif	sifnpmode(f->unit, PPP_IP, NPMODE_PASS);	/* assign a default route through the interface if required */	if (ipcp_wantoptions[f->unit].default_route) 	    if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))		default_route_set[f->unit] = 1;	/* Make a proxy ARP entry if requested. */	if (ipcp_wantoptions[f->unit].proxy_arp)	    if (sifproxyarp(f->unit, ho->hisaddr))		proxy_arp_set[f->unit] = 1;	ipcp_wantoptions[0].ouraddr = go->ouraddr;	notice("local  IP address %I", go->ouraddr);	notice("remote IP address %I", ho->hisaddr);	if (go->dnsaddr[0])	    notice("primary   DNS address %I", go->dnsaddr[0]);	if (go->dnsaddr[1])	    notice("secondary DNS address %I", go->dnsaddr[1]);    }    reset_link_stats(f->unit);    np_up(f->unit, PPP_IP);    ipcp_is_up = 1;    notify(ip_up_notifier, 0);    if (ip_up_hook)	ip_up_hook();    /*     * Execute the ip-up script, like this:     *	/etc/ppp/ip-up interface tty speed local-IP remote-IP     */    if (ipcp_script_state == s_down && ipcp_script_pid == 0) {	ipcp_script_state = s_up;	ipcp_script(_PATH_IPUP, 0);    }}/* * ipcp_down - IPCP has gone DOWN. * * Take the IP network interface down, clear its addresses * and delete routes through it. */static voidipcp_down(f)    fsm *f;{    IPCPDEBUG(("ipcp: down"));    /* XXX a bit IPv4-centric here, we only need to get the stats     * before the interface is marked down. */    /* XXX more correct: we must get the stats before running the notifiers,     * at least for the radius plugin */    update_link_stats(f->unit);    notify(ip_down_notifier, 0);    if (ip_down_hook)	ip_down_hook();    if (ipcp_is_up) {	ipcp_is_up = 0;	np_down(f->unit, PPP_IP);    }    sifvjcomp(f->unit, 0, 0, 0);    print_link_stats(); /* _after_ running the notifiers and ip_down_hook(),			 * because print_link_stats() sets link_stats_valid			 * to 0 (zero) */    /*     * If we are doing dial-on-demand, set the interface     * to queue up outgoing packets (for now).     */    if (demand) {	sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);    } else {	sifnpmode(f->unit, PPP_IP, NPMODE_DROP);	sifdown(f->unit);	ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,			 ipcp_hisoptions[f->unit].hisaddr);    }    /* Execute the ip-down script */    if (ipcp_script_state == s_up && ipcp_script_pid == 0) {	ipcp_script_state = s_down;	ipcp_script(_PATH_IPDOWN, 0);    }}/* * ipcp_clear_addrs() - clear the interface addresses, routes, * proxy arp entries, etc. */static voidipcp_clear_addrs(unit, ouraddr, hisaddr)    int unit;    u_int32_t ouraddr;  /* local address */    u_int32_t hisaddr;  /* remote address */{    if (proxy_arp_set[unit]) {	cifproxyarp(unit, hisaddr);	proxy_arp_set[unit] = 0;    }    if (default_route_set[unit]) {	cifdefaultroute(unit, ouraddr, hisaddr);	default_route_set[unit] = 0;    }    cifaddr(unit, ouraddr, hisaddr);}/* * ipcp_finished - possibly shut down the lower layers. */static voidipcp_finished(f)    fsm *f;{	if (ipcp_is_open) {		ipcp_is_open = 0;		np_finished(f->unit, PPP_IP);	}}/* * ipcp_script_done - called when the ip-up or ip-down script * has finished. */static voidipcp_script_done(arg)    void *arg;{    ipcp_script_pid = 0;    switch (ipcp_script_state) {    case s_up:	if (ipcp_fsm[0].state != OPENED) {	    ipcp_script_state = s_down;	    ipcp_script(_PATH_IPDOWN, 0);	}	break;    case s_down:	if (ipcp_fsm[0].state == OPENED) {	    ipcp_script_state = s_up;	    ipcp_script(_PATH_IPUP, 0);	}	break;    }}/* * ipcp_script - Execute a script with arguments * interface-name tty-name speed local-IP remote-IP. */static voidipcp_script(script, wait)    char *script;    int wait;{    char strspeed[32], strlocal[32], strremote[32];    char *argv[8];    slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);    slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr);    slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr);    argv[0] = script;    argv[1] = ifname;    argv[2] = devnam;    argv[3] = strspeed;    argv[4] = strlocal;    argv[5] = strremote;    argv[6] = ipparam;    argv[7] = NULL;    if (wait)	run_program(script, argv, 0, NULL, NULL, 1);    else	ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done,				      NULL, 0);}/* * create_resolv - create the replacement resolv.conf file */static voidcreate_resolv(peerdns1, peerdns2)    u_int32_t peerdns1, peerdns2;{    FILE *f;    f = fopen(_PATH_RESOLV, "w");    if (f == NULL) {	error("Failed to create %s: %m", _PATH_RESOLV);	return;    }    if (peerdns1)	fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1));    if (peerdns2)	fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2));    if (ferror(f))	error("Write failed to %s: %m", _PATH_RESOLV);    fclose(f);}/* * ipcp_printpkt - print the contents of an IPCP packet. */static char *ipcp_codenames[] = {    "ConfReq", "ConfAck", "ConfNak", "ConfRej",    "TermReq", "TermAck", "CodeRej"};static intipcp_printpkt(p, plen, printer, arg)    u_char *p;    int plen;    void (*printer) __P((void *, char *, ...));    void *arg;{    int code, id, len, olen;    u_char *pstart, *optend;    u_short cishort;    u_int32_t cilong;    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(ipcp_codenames) / sizeof(char *))	printer(arg, " %s", ipcp_codenames[code-1]);    else	printer(arg, " code=0x%x", code);    printer(arg, " id=0x%x", id);    len -= HEADERLEN;    switch (code) {    case CONFREQ:    case CONFACK:    case CONFNAK:    case CONFREJ:	/* print option list */	while (len >= 2) {	    GETCHAR(code, p);	    GETCHAR(olen, p);	    p -= 2;	    if (olen < 2 || olen > len) {		break;	    }	    printer(arg, " <");	    len -= olen;	    optend = p + olen;	    switch (code) {	    case CI_ADDRS:		if (olen == CILEN_ADDRS) {		    p += 2;		    GETLONG(cilong, p);		    printer(arg, "addrs %I", htonl(cilong));		    GETLONG(cilong, p);		    printer(arg, " %I", htonl(cilong));		}		break;	    case CI_COMPRESSTYPE:		if (olen >= CILEN_COMPRESS) {		    p += 2;		    GETSHORT(cishort, p);		    printer(arg, "compress ");		    switch (cishort) {		    case IPCP_VJ_COMP:			printer(arg, "VJ");			break;		    case IPCP_VJ_COMP_OLD:			printer(arg, "old-VJ");			break;		    default:			printer(arg, "0x%x", cishort);		    }		}		break;	    case CI_ADDR:		if (olen == CILEN_ADDR) {		    p += 2;		    GETLONG(cilong, p);		    printer(arg, "addr %I", htonl(cilong));		}		break;	    case CI_MS_DNS1:	    case CI_MS_DNS2:	        p += 2;		GETLONG(cilong, p);		printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1,			htonl(cilong));		break;	    case CI_MS_WINS1:	    case CI_MS_WINS2:	        p += 2;		GETLONG(cilong, p);		printer(arg, "ms-wins %I", htonl(cilong));		break;	    }	    while (p < optend) {		GETCHAR(code, p);		printer(arg, " %.2x", code);	    }	    printer(arg, ">");	}	break;    case TERMACK:    case TERMREQ:	if (len > 0 && *p >= ' ' && *p < 0x7f) {	    printer(arg, " ");	    print_string((char *)p, len, printer, arg);	    p += len;	    len = 0;	}	break;    }    /* print the rest of the bytes in the packet */    for (; len > 0; --len) {	GETCHAR(code, p);	printer(arg, " %.2x", code);    }    return p - pstart;}/* * ip_active_pkt - see if this IP packet is worth bringing the link up for. * We don't bring the link up for IP fragments or for TCP FIN packets * with no data. */#define IP_HDRLEN	20	/* bytes */#define IP_OFFMASK	0x1fff#ifndef IPPROTO_TCP#define IPPROTO_TCP	6#endif#define TCP_HDRLEN	20#define TH_FIN		0x01/* * We use these macros because the IP header may be at an odd address, * and some compilers might use word loads to get th_off or ip_hl. */#define net_short(x)	(((x)[0] << 8) + (x)[1])#define get_iphl(x)	(((unsigned char *)(x))[0] & 0xF)#define get_ipoff(x)	net_short((unsigned char *)(x) + 6)#define get_ipproto(x)	(((unsigned char *)(x))[9])#define get_tcpoff(x)	(((unsigned char *)(x))[12] >> 4)#define get_tcpflags(x)	(((unsigned char *)(x))[13])static intip_active_pkt(pkt, len)    u_char *pkt;    int len;{    u_char *tcp;    int hlen;    len -= PPP_HDRLEN;    pkt += PPP_HDRLEN;    if (len < IP_HDRLEN)	return 0;    if ((get_ipoff(pkt) & IP_OFFMASK) != 0)	return 0;    if (get_ipproto(pkt) != IPPROTO_TCP)	return 1;    hlen = get_iphl(pkt) * 4;    if (len < hlen + TCP_HDRLEN)	return 0;    tcp = pkt + hlen;    if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)	return 0;    return 1;}

⌨️ 快捷键说明

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