in net/ip/lwip_base/src/netif/ppp/ipcp.c [1885:2109]
static void ipcp_up(fsm *f) {
ppp_pcb *pcb = f->pcb;
u32_t mask;
ipcp_options *ho = &pcb->ipcp_hisoptions;
ipcp_options *go = &pcb->ipcp_gotoptions;
ipcp_options *wo = &pcb->ipcp_wantoptions;
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) {
ppp_error("Peer refused to agree to our IP address");
ipcp_close(f->pcb, "Refused our IP address");
return;
}
if (go->ouraddr == 0) {
ppp_error("Could not determine local IP address");
ipcp_close(f->pcb, "Could not determine local IP address");
return;
}
if (ho->hisaddr == 0 && !pcb->settings.noremoteip) {
ho->hisaddr = lwip_htonl(0x0a404040);
ppp_warn("Could not determine remote IP address: defaulting to %I",
ho->hisaddr);
}
#if 0 /* UNUSED */
script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
if (ho->hisaddr != 0)
script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
#endif /* UNUSED */
#if LWIP_DNS
if (!go->req_dns1)
go->dnsaddr[0] = 0;
if (!go->req_dns2)
go->dnsaddr[1] = 0;
#if 0 /* UNUSED */
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);
#endif /* UNUSED */
if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]);
#if 0 /* UNUSED */
script_setenv("USEPEERDNS", "1", 0);
create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
#endif /* UNUSED */
}
#endif /* LWIP_DNS */
/*
* Check that the peer is allowed to use the IP address it wants.
*/
if (ho->hisaddr != 0) {
u32_t addr = lwip_ntohl(ho->hisaddr);
if ((addr >> IP_CLASSA_NSHIFT) == IP_LOOPBACKNET
|| IP_MULTICAST(addr) || IP_BADCLASS(addr)
/*
* For now, consider that PPP in server mode with peer required
* to authenticate must provide the peer IP address, reject any
* IP address wanted by peer different than the one we wanted.
*/
#if PPP_SERVER && PPP_AUTH_SUPPORT
|| (pcb->settings.auth_required && wo->hisaddr != ho->hisaddr)
#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */
) {
ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr);
ipcp_close(pcb, "Unauthorized remote IP address");
return;
}
}
#if 0 /* Unused */
/* Upstream checking code */
if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) {
ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr);
ipcp_close(f->unit, "Unauthorized remote IP address");
return;
}
#endif /* Unused */
#if VJ_SUPPORT
/* set tcp compression */
sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex);
#endif /* VJ_SUPPORT */
#if DEMAND_SUPPORT
/*
* 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,
wo->replace_default_route);
if (go->ouraddr != wo->ouraddr) {
ppp_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 && wo->hisaddr != 0) {
ppp_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 = get_mask(go->ouraddr);
if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) {
#if PPP_DEBUG
ppp_warn("Interface configuration failed");
#endif /* PPP_DEBUG */
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(pcb, go->ouraddr, ho->hisaddr,
wo->replace_default_route))
default_route_set[f->unit] = 1;
#if 0 /* UNUSED - PROXY ARP */
/* Make a proxy ARP entry if requested. */
if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
if (sifproxyarp(pcb, ho->hisaddr))
proxy_arp_set[f->unit] = 1;
#endif /* UNUSED - PROXY ARP */
}
demand_rexmit(PPP_IP,go->ouraddr);
sifnpmode(pcb, PPP_IP, NPMODE_PASS);
} else
#endif /* DEMAND_SUPPORT */
{
/*
* Set IP addresses and (if specified) netmask.
*/
mask = get_mask(go->ouraddr);
#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) {
#if PPP_DEBUG
ppp_warn("Interface configuration failed");
#endif /* PPP_DEBUG */
ipcp_close(f->pcb, "Interface configuration failed");
return;
}
#endif
/* bring the interface up for IP */
if (!sifup(pcb)) {
#if PPP_DEBUG
ppp_warn("Interface failed to come up");
#endif /* PPP_DEBUG */
ipcp_close(f->pcb, "Interface configuration failed");
return;
}
#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) {
#if PPP_DEBUG
ppp_warn("Interface configuration failed");
#endif /* PPP_DEBUG */
ipcp_close(f->unit, "Interface configuration failed");
return;
}
#endif
#if DEMAND_SUPPORT
sifnpmode(pcb, PPP_IP, NPMODE_PASS);
#endif /* DEMAND_SUPPORT */
#if 0 /* UNUSED */
/* assign a default route through the interface if required */
if (wo->default_route)
if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr,
wo->replace_default_route))
pcb->default_route_set = 1;
#endif /* UNUSED */
#if 0 /* UNUSED - PROXY ARP */
/* Make a proxy ARP entry if requested. */
if (ho->hisaddr != 0 && wo->proxy_arp)
if (sifproxyarp(pcb, ho->hisaddr))
pcb->proxy_arp_set = 1;
#endif /* UNUSED - PROXY ARP */
wo->ouraddr = go->ouraddr;
ppp_notice("local IP address %I", go->ouraddr);
if (ho->hisaddr != 0)
ppp_notice("remote IP address %I", ho->hisaddr);
#if LWIP_DNS
if (go->dnsaddr[0])
ppp_notice("primary DNS address %I", go->dnsaddr[0]);
if (go->dnsaddr[1])
ppp_notice("secondary DNS address %I", go->dnsaddr[1]);
#endif /* LWIP_DNS */
}
#if PPP_STATS_SUPPORT
reset_link_stats(f->unit);
#endif /* PPP_STATS_SUPPORT */
np_up(pcb, PPP_IP);
pcb->ipcp_is_up = 1;
#if PPP_NOTIFY
notify(ip_up_notifier, 0);
#endif /* PPP_NOTIFY */
#if 0 /* UNUSED */
if (ip_up_hook)
ip_up_hook();
#endif /* UNUSED */
}