📄 ipcp.c
字号:
ciaddr2 = htonl(tl); IPCPDEBUG((LOG_INFO, "%s)", ip_ntoa(ciaddr2))); if (ciaddr2 != wo->ouraddr) { if (ciaddr2 == 0 || !wo->accept_local) { orc = CONFNAK; if (!reject_if_disagree) { DECPTR(sizeof (long), p); tl = ntohl(wo->ouraddr); PUTLONG(tl, p); } } else { go->ouraddr = ciaddr2; /* accept peer's idea */ } } ho->neg_addr = 1; ho->old_addrs = 1; ho->hisaddr = ciaddr1; ho->ouraddr = ciaddr2; break; case CI_ADDR: IPCPDEBUG((LOG_INFO, "ipcp: received ADDR ")); if (!ao->neg_addr || cilen != CILEN_ADDR) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } /* * If he has no address, or if we both have his address but * disagree about it, then NAK it with our idea. * In particular, if we don't know his address, but he does, * then accept it. */ GETLONG(tl, p); /* Parse source address (his) */ ciaddr1 = htonl(tl); IPCPDEBUG((LOG_INFO, "(%s)", ip_ntoa(ciaddr1))); if (ciaddr1 != wo->hisaddr && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { DECPTR(sizeof (long), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } } ho->neg_addr = 1; ho->hisaddr = ciaddr1; break; 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 = wo->cflag; } else { ho->old_vj = 1; ho->maxslotindex = MAX_STATES - 1; ho->cflag = 1; } break; default: orc = CONFREJ; break; }endswitch: IPCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc))); if (orc == CONFACK && /* Good CI */ rc != CONFACK) /* but prior CI wasnt? */ 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((char *)cip, (char *)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_long mask; ipcp_options *ho = &ppp_if[f->unit]->ipcp_hisoptions; ipcp_options *go = &ppp_if[f->unit]->ipcp_gotoptions; 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 = ppp_if[f->unit]->ipcp_wantoptions.hisaddr; if (ho->hisaddr == 0) { syslog(LOG_ERR, "Could not determine remote IP address"); ipcp_close(f->unit); return; } if (go->ouraddr == 0) { 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)) { syslog(LOG_ERR, "Peer is not authorized to use remote address %s", ip_ntoa(ho->hisaddr)); ipcp_close(f->unit); return; } syslog (LOG_NOTICE, "local IP address %s", ip_ntoa(go->ouraddr)); 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 (ppp_if[f->unit]->ipcp_wantoptions.default_route) if (sifdefaultroute(f->unit, ho->hisaddr)) go->default_route = 1; /* Make a proxy ARP entry if requested. */ if (ppp_if[f->unit]->ipcp_wantoptions.proxy_arp) if (sifproxyarp(f->unit, ho->hisaddr)) go->proxy_arp = 1;}/* * 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_long ouraddr, hisaddr; IPCPDEBUG((LOG_INFO, "ipcp: down")); ouraddr = ppp_if[f->unit]->ipcp_gotoptions.ouraddr; hisaddr = ppp_if[f->unit]->ipcp_hisoptions.hisaddr; if (ppp_if[f->unit]->ipcp_gotoptions.proxy_arp) cifproxyarp(f->unit, hisaddr); if (ppp_if[f->unit]->ipcp_gotoptions.default_route) cifdefaultroute(f->unit, hisaddr); sifdown(f->unit); cifaddr(f->unit, ouraddr, hisaddr);}#ifdef notyet/* * 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]; sprintf(strspeed, "%d", ppp_if[f->unit]->baud_rate); strcpy(strlocal, ip_ntoa(ppp_if[f->unit]->ipcp_gotoptions.ouraddr)); strcpy(strremote, ip_ntoa(ppp_if[f->unit]->ipcp_hisoptions.hisaddr)); argv[0] = script; argv[1] = ppp_if[f->unit]->ifname; argv[2] = ppp_if[f->unit]->devname; argv[3] = strspeed; argv[4] = strlocal; argv[5] = strremote; argv[6] = NULL; run_program(script, argv, 0);}#endif /* notyet *//* * 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_long 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 + -