📄 ipcp.c
字号:
#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 + -