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

📄 ipcp.c

📁 Unix/Linux NAPT协议解析源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef USE_MS_DNS	/* Handle Microsoft DNS Stuff */	case CI_MS_DNS1:	    IPCPDEBUG((LOG_INFO, "ipcp: received DNS Request "));	    /* If we do not have a DNS address then we cannot send it */        wo->dnsaddr[0]=dns_addr.s_addr;        wo->dnsaddr[1]=dns2_addr.s_addr;	    if (wo->dnsaddr[0] == 0 ||		cilen != CILEN_ADDR) {	/* Check CI length */		IPCPDEBUG((LOG_INFO, "DNS failed due to %d, %d, %d", wo->dnsaddr[0], cilen, CILEN_ADDR));		orc = CONFREJ;		/* Reject CI */		break;	    }	    GETLONG(tl,p);	    if (htonl(tl) != wo->dnsaddr[0]) {                DECPTR(sizeof (long),p);		tl = ntohl(wo->dnsaddr[0]);		PUTLONG(tl, p);		orc = CONFNAK;            }            break;	case CI_MS_WINS1:	    IPCPDEBUG((LOG_INFO, "ipcp: received WINS Request "));	    /* If we do not have a WINS address then we cannot send it */	    if (wo->winsaddr[0] == 0 ||		cilen != CILEN_ADDR) {	/* Check CI length */		orc = CONFREJ;		/* Reject CI */		break;	    }	    GETLONG(tl,p);	    if (htonl(tl) != wo->winsaddr[0]) {                DECPTR(sizeof (long),p);		tl = ntohl(wo->winsaddr[0]);		PUTLONG(tl, p);		orc = CONFNAK;            }            break;	case CI_MS_DNS2:	    IPCPDEBUG((LOG_INFO, "ipcp: received DNS Request "));	    /* If we do not have a DNS address then we cannot send it */	    if (wo->dnsaddr[0] == 0 ||  /* Yes, this is the first one! */		cilen != CILEN_ADDR) {	/* Check CI length */		orc = CONFREJ;		/* Reject CI */		break;	    }	    GETLONG(tl,p);	    if (htonl(tl) != wo->dnsaddr[1]) { /* and this is the 2nd one */                DECPTR(sizeof (long),p);		tl = ntohl(wo->dnsaddr[1]);		PUTLONG(tl, p);		orc = CONFNAK;            }            break;	case CI_MS_WINS2:	    IPCPDEBUG((LOG_INFO, "ipcp: received WINS Request "));	    /* If we do not have a WINS address then we cannot send it */	    if (wo->winsaddr[0] == 0 ||  /* Yes, this is the first one! */		cilen != CILEN_ADDR) {	/* Check CI length */		orc = CONFREJ;		/* Reject CI */		break;	    }	    GETLONG(tl,p);	    if (htonl(tl) != wo->winsaddr[1]) { /* and this is the 2nd one */                DECPTR(sizeof (long),p);		tl = ntohl(wo->winsaddr[1]);		PUTLONG(tl, p);		orc = CONFNAK;            }            break;#endif	case CI_COMPRESSTYPE:	    IPCPDEBUG((LOG_INFO, "ipcp: received COMPRESSTYPE "));	    if (!ao->neg_vj ||		(cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {		orc = CONFREJ;		break;	    }	    GETSHORT(cishort, p);	    IPCPDEBUG((LOG_INFO, "(%d)", cishort));	    if (!(cishort == IPCP_VJ_COMP ||		  (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {		orc = CONFREJ;		break;	    }	    ho->neg_vj = 1;	    ho->vj_protocol = cishort;	    if (cilen == CILEN_VJ) {		GETCHAR(maxslotindex, p);		if (maxslotindex > ao->maxslotindex) { 		    orc = CONFNAK;		    if (!reject_if_disagree){			DECPTR(1, p);			PUTCHAR(ao->maxslotindex, p);		    }		}		GETCHAR(cflag, p);		if (cflag && !ao->cflag) {		    orc = CONFNAK;		    if (!reject_if_disagree){			DECPTR(1, p);			PUTCHAR(wo->cflag, p);		    }		}		ho->maxslotindex = maxslotindex;		ho->cflag = cflag;	    } else {		ho->old_vj = 1;		ho->maxslotindex = MAX_STATES - 1;		ho->cflag = 1;	    }	    break;	default:	    orc = CONFREJ;	    break;	}endswitch:	IPCPDEBUG((LOG_INFO, " (%s)\n", CODENAME(orc)));	if (orc == CONFACK &&		/* Good CI */	    rc != CONFACK)		/*  but prior CI wasn't? */	    continue;			/* Don't send this one */	if (orc == CONFNAK) {		/* Nak this CI? */	    if (reject_if_disagree)	/* Getting fed up with sending NAKs? */		orc = CONFREJ;		/* Get tough if so */	    else {		if (rc == CONFREJ)	/* Rejecting prior CI? */		    continue;		/* Don't send this one */		if (rc == CONFACK) {	/* Ack'd all prior CIs? */		    rc = CONFNAK;	/* Not anymore... */		    ucp = inp;		/* Backup */		}	    }	}	if (orc == CONFREJ &&		/* Reject this CI */	    rc != CONFREJ) {		/*  but no prior ones? */	    rc = CONFREJ;	    ucp = inp;			/* Backup */	}	/* Need to move CI? */	if (ucp != cip)	    BCOPY(cip, ucp, cilen);	/* Move it */	/* Update output pointer */	INCPTR(cilen, ucp);    }    /*     * If we aren't rejecting this packet, and we want to negotiate     * their address, and they didn't send their address, then we     * send a NAK with a CI_ADDR option appended.  We assume the     * input buffer is long enough that we can append the extra     * option safely.     */    if (rc != CONFREJ && !ho->neg_addr &&	wo->req_addr && !reject_if_disagree) {	if (rc == CONFACK) {	    rc = CONFNAK;	    ucp = inp;			/* reset pointer */	    wo->req_addr = 0;		/* don't ask again */	}	PUTCHAR(CI_ADDR, ucp);	PUTCHAR(CILEN_ADDR, ucp);	tl = ntohl(wo->hisaddr);	PUTLONG(tl, ucp);    }    *len = ucp - inp;			/* Compute output length */    IPCPDEBUG((LOG_INFO, "ipcp: returning Configure-%s", CODENAME(rc)));    return (rc);			/* Return final code */}/* * 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];    IPCPDEBUG((LOG_INFO, "ipcp: up"));    go->default_route = 0;    go->proxy_arp = 0;    /*     * We must have a non-zero IP address for both ends of the link.     */    if (!ho->neg_addr)	ho->hisaddr = ipcp_wantoptions[f->unit].hisaddr;    if (ho->hisaddr == 0) {	do_syslog(LOG_ERR, "Could not determine remote IP address");	ipcp_close(f->unit);	return;    }    if (go->ouraddr == 0) {	do_syslog(LOG_ERR, "Could not determine local IP address");	ipcp_close(f->unit);	return;    }    /*     * Check that the peer is allowed to use the IP address it wants.     */    if (!auth_ip_addr(f->unit, ho->hisaddr)) {	do_syslog(LOG_ERR, "Peer is not authorized to use remote address %s",	       ip_ntoa(ho->hisaddr));	ipcp_close(f->unit);	return;    }    do_syslog(LOG_NOTICE, "local  IP address %s", ip_ntoa(go->ouraddr));    do_syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr));    /*     * Set IP addresses and (if specified) netmask.     */    mask = GetMask(go->ouraddr);    if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {	IPCPDEBUG((LOG_WARNING, "sifaddr failed"));	ipcp_close(f->unit);	return;    }    /* set tcp compression */    sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);    /* bring the interface up for IP */    if (!sifup(f->unit)) {	IPCPDEBUG((LOG_WARNING, "sifup failed"));	ipcp_close(f->unit);	return;    }    /* assign a default route through the interface if required */    if (ipcp_wantoptions[f->unit].default_route) 	if (sifdefaultroute(f->unit, ho->hisaddr))	    go->default_route = 1;    /* Make a proxy ARP entry if requested. */    if (ipcp_wantoptions[f->unit].proxy_arp)	if (sifproxyarp(f->unit, ho->hisaddr))	    go->proxy_arp = 1;    /*     * Execute the ip-up script, like this:     *	/etc/ppp/ip-up interface tty speed local-IP remote-IP     */    ipcp_script(f, _PATH_IPUP);}/* * 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;{    u_int32_t ouraddr, hisaddr;    IPCPDEBUG((LOG_INFO, "ipcp: down"));    ouraddr = ipcp_gotoptions[f->unit].ouraddr;    hisaddr = ipcp_hisoptions[f->unit].hisaddr;    if (ipcp_gotoptions[f->unit].proxy_arp)	cifproxyarp(f->unit, hisaddr);    if (ipcp_gotoptions[f->unit].default_route) 	cifdefaultroute(f->unit, hisaddr);    sifdown(f->unit);    cifaddr(f->unit, ouraddr, hisaddr);    /* Execute the ip-down script */    ipcp_script(f, _PATH_IPDOWN);}/* * ipcp_script - Execute a script with arguments * interface-name tty-name speed local-IP remote-IP. */static voidipcp_script(f, script)    fsm *f;    char *script;{    char strspeed[32], strlocal[32], strremote[32];    char *argv[8];    snprintf(strspeed, sizeof(strspeed), "%d", baud_rate);    strncpy2(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr), sizeof(strlocal));    strncpy2(strremote, ip_ntoa(ipcp_hisoptions[f->unit].hisaddr), sizeof(strremote));    argv[0] = script;    argv[1] = ifname;    argv[2] = devnam;    argv[3] = strspeed;    argv[4] = strlocal;    argv[5] = strremote;    argv[6] = ipparam;    argv[7] = NULL;    run_program(script, argv, 0);}/* * ipcp_printpkt - print the contents of an IPCP packet. */char *ipcp_codenames[] = {    "ConfReq", "ConfAck", "ConfNak", "ConfRej",    "TermReq", "TermAck", "CodeRej"};intipcp_printpkt(p, plen, printer, arg)    u_char *p;    int plen;    void (*printer)();    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 %s", ip_ntoa(htonl(cilong)));		    GETLONG(cilong, p);		    printer(arg, " %s", ip_ntoa(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 %s", ip_ntoa(htonl(cilong)));		}		break;	    }	    while (p < optend) {		GETCHAR(code, p);		printer(arg, " %.2x", code);	    }	    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;}

⌨️ 快捷键说明

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