44#if PPP_SUPPORT && PPP_IPV4_SUPPORT
58#include <netinet/in.h>
73bool disable_defaultip = 0;
93struct notifier *ip_up_notifier =
NULL;
94struct notifier *ip_down_notifier =
NULL;
99static int default_route_set[NUM_PPP];
100static int proxy_arp_set[NUM_PPP];
101static int ipcp_is_up;
102static int ipcp_is_open;
103static bool ask_for_local;
106static char vj_value[8];
107static char netmask_str[20];
113static void ipcp_resetci(fsm *
f);
114static int ipcp_cilen(fsm *
f);
115static void ipcp_addci(fsm *
f,
u_char *ucp,
int *lenp);
117static int ipcp_nakci(fsm *
f,
u_char *
p,
int len,
int treat_as_reject);
119static int ipcp_reqci(fsm *
f,
u_char *inp,
int *
len,
int reject_if_disagree);
120static void ipcp_up(fsm *
f);
121static void ipcp_down(fsm *
f);
122static void ipcp_finished(fsm *
f);
124static const fsm_callbacks ipcp_callbacks = {
146static int setvjslots (
char **);
147static int setdnsaddr (
char **);
148static int setwinsaddr (
char **);
149static int setnetmask (
char **);
150int setipaddr (
char *,
char **,
int);
152static void printipaddr (option_t *,
void (*)(
void *,
char *,...),
void *);
154static option_t ipcp_option_list[] = {
155 {
"noip", o_bool, &ipcp_protent.enabled_flag,
156 "Disable IP and IPCP" },
157 {
"-ip", o_bool, &ipcp_protent.enabled_flag,
158 "Disable IP and IPCP", OPT_ALIAS },
160 {
"novj", o_bool, &ipcp_wantoptions[0].neg_vj,
161 "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj },
162 {
"-vj", o_bool, &ipcp_wantoptions[0].neg_vj,
163 "Disable VJ compression", OPT_ALIAS | OPT_A2CLR,
164 &ipcp_allowoptions[0].neg_vj },
166 {
"novjccomp", o_bool, &ipcp_wantoptions[0].cflag,
167 "Disable VJ connection-ID compression", OPT_A2CLR,
168 &ipcp_allowoptions[0].cflag },
169 {
"-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
170 "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR,
171 &ipcp_allowoptions[0].cflag },
173 {
"vj-max-slots", o_special, (
void *)setvjslots,
174 "Set maximum VJ header slots",
175 OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value },
177 {
"ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
178 "Accept peer's address for us", 1 },
179 {
"ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,
180 "Accept peer's address for it", 1 },
182 {
"ipparam", o_string, &ipparam,
183 "Set ip script parameter", OPT_PRIO },
185 {
"noipdefault", o_bool, &disable_defaultip,
186 "Don't use name for default IP adrs", 1 },
188 {
"ms-dns", 1, (
void *)setdnsaddr,
189 "DNS address for the peer's use" },
190 {
"ms-wins", 1, (
void *)setwinsaddr,
191 "Nameserver for SMB over TCP/IP for peer" },
193 {
"ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
194 "Set timeout for IPCP", OPT_PRIO },
195 {
"ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,
196 "Set max #xmits for term-reqs", OPT_PRIO },
197 {
"ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,
198 "Set max #xmits for conf-reqs", OPT_PRIO },
199 {
"ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,
200 "Set max #conf-naks for IPCP", OPT_PRIO },
202 {
"defaultroute", o_bool, &ipcp_wantoptions[0].default_route,
203 "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },
204 {
"nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,
205 "disable defaultroute option", OPT_A2CLR,
206 &ipcp_wantoptions[0].default_route },
207 {
"-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
208 "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
209 &ipcp_wantoptions[0].default_route },
211 {
"replacedefaultroute", o_bool,
212 &ipcp_wantoptions[0].replace_default_route,
213 "Replace default route", 1
215 {
"noreplacedefaultroute", o_bool,
216 &ipcp_allowoptions[0].replace_default_route,
217 "Never replace default route", OPT_A2COPY,
218 &ipcp_wantoptions[0].replace_default_route },
219 {
"proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
220 "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
221 {
"noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
222 "disable proxyarp option", OPT_A2CLR,
223 &ipcp_wantoptions[0].proxy_arp },
224 {
"-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
225 "disable proxyarp option", OPT_ALIAS | OPT_A2CLR,
226 &ipcp_wantoptions[0].proxy_arp },
228 {
"usepeerdns", o_bool, &usepeerdns,
229 "Ask peer for DNS address(es)", 1 },
231 {
"netmask", o_special, (
void *)setnetmask,
232 "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },
234 {
"ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs,
235 "Disable old-style IP-Addresses usage", OPT_A2CLR,
236 &ipcp_allowoptions[0].old_addrs },
237 {
"ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr,
238 "Disable IP-Address usage", OPT_A2CLR,
239 &ipcp_allowoptions[0].neg_addr },
241 {
"noremoteip", o_bool, &noremoteip,
242 "Allow peer to have no IP address", 1 },
244 {
"nosendip", o_bool, &ipcp_wantoptions[0].neg_addr,
245 "Don't send our IP address to peer", OPT_A2CLR,
246 &ipcp_wantoptions[0].old_addrs},
248 {
"IP addresses", o_wild, (
void *) &setipaddr,
249 "set local and remote IP addresses",
250 OPT_NOARG | OPT_A2PRINTER, (
void *) &printipaddr },
259static void ipcp_init(ppp_pcb *pcb);
260static void ipcp_open(ppp_pcb *pcb);
261static void ipcp_close(ppp_pcb *pcb,
const char *
reason);
262static void ipcp_lowerup(ppp_pcb *pcb);
263static void ipcp_lowerdown(ppp_pcb *pcb);
264static void ipcp_input(ppp_pcb *pcb,
u_char *
p,
int len);
265static void ipcp_protrej(ppp_pcb *pcb);
267static int ipcp_printpkt(
const u_char *
p,
int plen,
268 void (*printer) (
void *,
const char *, ...),
void *
arg);
271static void ip_check_options (
void);
274static int ip_demand_conf (
int);
275static int ip_active_pkt (
u_char *,
int);
281const struct protent ipcp_protent = {
310static void ipcp_clear_addrs(ppp_pcb *pcb,
u32_t ouraddr,
u32_t hisaddr,
u8_t replacedefaultroute);
316#define CILEN_COMPRESS 4
319#define CILEN_ADDRS 10
322#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
323 (x) == CONFNAK ? "NAK" : "REJ")
335 slprintf(
b,
sizeof(
b),
"%I", ipaddr);
356 if (value < 2 || value > 16) {
357 option_error(
"vj-max-slots value must be between 2 and 16");
360 ipcp_wantoptions [0].maxslotindex =
361 ipcp_allowoptions[0].maxslotindex =
value - 1;
362 slprintf(vj_value,
sizeof(vj_value),
"%d",
value);
377 if (dns == (
u32_t) -1) {
379 option_error(
"invalid address parameter '%s' for ms-dns option",
383 dns = *(
u32_t *)hp->h_addr;
389 if (ipcp_allowoptions[0].dnsaddr[1] == 0)
390 ipcp_allowoptions[0].dnsaddr[0] = dns;
392 ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1];
395 ipcp_allowoptions[0].dnsaddr[1] = dns;
413 if (wins == (
u32_t) -1) {
415 option_error(
"invalid address parameter '%s' for ms-wins option",
419 wins = *(
u32_t *)hp->h_addr;
425 if (ipcp_allowoptions[0].winsaddr[1] == 0)
426 ipcp_allowoptions[0].winsaddr[0] = wins;
428 ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1];
431 ipcp_allowoptions[0].winsaddr[1] = wins;
451 ipcp_options *wo = &ipcp_wantoptions[0];
452 static int prio_local = 0, prio_remote = 0;
465 if (colon !=
arg && option_priority >= prio_local) {
469 option_error(
"unknown host: %s",
arg);
474 if (bad_ip_adrs(
local)) {
475 option_error(
"bad local IP address %s", ip_ntoa(
local));
481 prio_local = option_priority;
487 if (*++colon !=
'\0' && option_priority >= prio_remote) {
490 option_error(
"unknown host: %s", colon);
493 remote = *(
u32_t *)hp->h_addr;
494 if (remote_name[0] == 0)
495 strlcpy(remote_name, colon,
sizeof(remote_name));
497 if (bad_ip_adrs(remote)) {
498 option_error(
"bad remote IP address %s", ip_ntoa(remote));
502 wo->hisaddr = remote;
503 prio_remote = option_priority;
510printipaddr(opt, printer,
arg)
512 void (*printer) (
void *,
char *, ...);
515 ipcp_options *wo = &ipcp_wantoptions[0];
517 if (wo->ouraddr != 0)
518 printer(
arg,
"%I", wo->ouraddr);
520 if (wo->hisaddr != 0)
521 printer(
arg,
"%I", wo->hisaddr);
540 n = parse_dotted_ip(
p, &
mask);
544 if (
n == 0 ||
p[
n] != 0 || (netmask & ~
mask) != 0) {
545 option_error(
"invalid netmask value '%s'", *
argv);
550 slprintf(netmask_str,
sizeof(netmask_str),
"%I",
mask);
556parse_dotted_ip(
p, vp)
592static void ipcp_init(ppp_pcb *pcb) {
593 fsm *
f = &pcb->ipcp_fsm;
595 ipcp_options *wo = &pcb->ipcp_wantoptions;
596 ipcp_options *ao = &pcb->ipcp_allowoptions;
599 f->protocol = PPP_IPCP;
600 f->callbacks = &ipcp_callbacks;
609 f->maxnakloops = 100;
612 memset(wo, 0,
sizeof(*wo));
613 memset(ao, 0,
sizeof(*ao));
616 wo->neg_addr = wo->old_addrs = 1;
619 wo->vj_protocol = IPCP_VJ_COMP;
620 wo->maxslotindex = MAX_STATES - 1;
626 wo->default_route = 1;
629 ao->neg_addr = ao->old_addrs = 1;
636 ao->maxslotindex = MAX_STATES - 1;
646 ao->default_route = 1;
654static void ipcp_open(ppp_pcb *pcb) {
655 fsm *
f = &pcb->ipcp_fsm;
657 pcb->ipcp_is_open = 1;
664static void ipcp_close(ppp_pcb *pcb,
const char *
reason) {
665 fsm *
f = &pcb->ipcp_fsm;
673static void ipcp_lowerup(ppp_pcb *pcb) {
674 fsm *
f = &pcb->ipcp_fsm;
682static void ipcp_lowerdown(ppp_pcb *pcb) {
683 fsm *
f = &pcb->ipcp_fsm;
691static void ipcp_input(ppp_pcb *pcb,
u_char *
p,
int len) {
692 fsm *
f = &pcb->ipcp_fsm;
693 fsm_input(
f,
p,
len);
702static void ipcp_protrej(ppp_pcb *pcb) {
703 fsm *
f = &pcb->ipcp_fsm;
712static void ipcp_resetci(fsm *
f) {
713 ppp_pcb *pcb =
f->pcb;
714 ipcp_options *wo = &pcb->ipcp_wantoptions;
715 ipcp_options *go = &pcb->ipcp_gotoptions;
716 ipcp_options *ao = &pcb->ipcp_allowoptions;
718 wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
719 (ao->neg_addr || ao->old_addrs);
720 if (wo->ouraddr == 0)
721 wo->accept_local = 1;
722 if (wo->hisaddr == 0)
723 wo->accept_remote = 1;
725 wo->req_dns1 = wo->req_dns2 = pcb->settings.usepeerdns;
728 if (!pcb->ask_for_local)
731 if (ip_choose_hook) {
732 ip_choose_hook(&wo->hisaddr);
734 wo->accept_remote = 0;
738 BZERO(&pcb->ipcp_hisoptions,
sizeof(ipcp_options));
746static int ipcp_cilen(fsm *
f) {
747 ppp_pcb *pcb =
f->pcb;
748 ipcp_options *go = &pcb->ipcp_gotoptions;
750 ipcp_options *wo = &pcb->ipcp_wantoptions;
752 ipcp_options *ho = &pcb->ipcp_hisoptions;
754#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0)
756#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
758#define LENCIADDR(neg) (neg ? CILEN_ADDR : 0)
760#define LENCIDNS(neg) LENCIADDR(neg)
763#define LENCIWINS(neg) LENCIADDR(neg)
770 if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs)
774 if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
777 if (ho->neg_vj && ho->old_vj) {
780 go->vj_protocol = ho->vj_protocol;
785 return (LENCIADDRS(!go->neg_addr && go->old_addrs) +
787 LENCIVJ(go->neg_vj, go->old_vj) +
789 LENCIADDR(go->neg_addr) +
791 LENCIDNS(go->req_dns1) +
792 LENCIDNS(go->req_dns2) +
795 LENCIWINS(go->winsaddr[0]) +
796 LENCIWINS(go->winsaddr[1]) +
806static void ipcp_addci(fsm *
f,
u_char *ucp,
int *lenp) {
807 ppp_pcb *pcb =
f->pcb;
808 ipcp_options *go = &pcb->ipcp_gotoptions;
811#define ADDCIADDRS(opt, neg, val1, val2) \
813 if (len >= CILEN_ADDRS) { \
816 PUTCHAR(CILEN_ADDRS, ucp); \
817 l = lwip_ntohl(val1); \
819 l = lwip_ntohl(val2); \
821 len -= CILEN_ADDRS; \
827#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
829 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
830 if (len >= vjlen) { \
832 PUTCHAR(vjlen, ucp); \
833 PUTSHORT(val, ucp); \
835 PUTCHAR(maxslotindex, ucp); \
836 PUTCHAR(cflag, ucp); \
844#define ADDCIADDR(opt, neg, val) \
846 if (len >= CILEN_ADDR) { \
849 PUTCHAR(CILEN_ADDR, ucp); \
850 l = lwip_ntohl(val); \
858#define ADDCIDNS(opt, neg, addr) \
860 if (len >= CILEN_ADDR) { \
863 PUTCHAR(CILEN_ADDR, ucp); \
864 l = lwip_ntohl(addr); \
873#define ADDCIWINS(opt, addr) \
875 if (len >= CILEN_ADDR) { \
878 PUTCHAR(CILEN_ADDR, ucp); \
879 l = lwip_ntohl(addr); \
887 ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
891 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
892 go->maxslotindex, go->cflag);
895 ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
898 ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
900 ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
904 ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
906 ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
922 ppp_pcb *pcb =
f->pcb;
923 ipcp_options *go = &pcb->ipcp_gotoptions;
928 u_char cimaxslotindex, cicflag;
937#define ACKCIADDRS(opt, neg, val1, val2) \
940 if ((len -= CILEN_ADDRS) < 0) \
942 GETCHAR(citype, p); \
944 if (cilen != CILEN_ADDRS || \
948 cilong = lwip_htonl(l); \
949 if (val1 != cilong) \
952 cilong = lwip_htonl(l); \
953 if (val2 != cilong) \
958#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
960 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
961 if ((len -= vjlen) < 0) \
963 GETCHAR(citype, p); \
965 if (cilen != vjlen || \
968 GETSHORT(cishort, p); \
969 if (cishort != val) \
972 GETCHAR(cimaxslotindex, p); \
973 if (cimaxslotindex != maxslotindex) \
975 GETCHAR(cicflag, p); \
976 if (cicflag != cflag) \
982#define ACKCIADDR(opt, neg, val) \
985 if ((len -= CILEN_ADDR) < 0) \
987 GETCHAR(citype, p); \
989 if (cilen != CILEN_ADDR || \
993 cilong = lwip_htonl(l); \
999#define ACKCIDNS(opt, neg, addr) \
1002 if ((len -= CILEN_ADDR) < 0) \
1004 GETCHAR(citype, p); \
1005 GETCHAR(cilen, p); \
1006 if (cilen != CILEN_ADDR || citype != opt) \
1009 cilong = lwip_htonl(l); \
1010 if (addr != cilong) \
1016#define ACKCIWINS(opt, addr) \
1019 if ((len -= CILEN_ADDR) < 0) \
1021 GETCHAR(citype, p); \
1022 GETCHAR(cilen, p); \
1023 if (cilen != CILEN_ADDR || citype != opt) \
1026 cilong = lwip_htonl(l); \
1027 if (addr != cilong) \
1032 ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
1036 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
1037 go->maxslotindex, go->cflag);
1040 ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
1043 ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
1045 ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
1049 ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]);
1051 ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]);
1062 IPCPDEBUG((
"ipcp_ackci: received bad Ack!"));
1076static int ipcp_nakci(fsm *
f,
u_char *
p,
int len,
int treat_as_reject) {
1077 ppp_pcb *pcb =
f->pcb;
1078 ipcp_options *go = &pcb->ipcp_gotoptions;
1081 u_char cimaxslotindex, cicflag;
1084 u32_t ciaddr1, ciaddr2,
l;
1091 BZERO(&
no,
sizeof(
no));
1099#define NAKCIADDRS(opt, neg, code) \
1101 (cilen = p[1]) == CILEN_ADDRS && \
1107 ciaddr1 = lwip_htonl(l); \
1109 ciaddr2 = lwip_htonl(l); \
1115#define NAKCIVJ(opt, neg, code) \
1117 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
1122 GETSHORT(cishort, p); \
1128#define NAKCIADDR(opt, neg, code) \
1130 (cilen = p[1]) == CILEN_ADDR && \
1136 ciaddr1 = lwip_htonl(l); \
1142#define NAKCIDNS(opt, neg, code) \
1144 ((cilen = p[1]) == CILEN_ADDR) && \
1150 cidnsaddr = lwip_htonl(l); \
1160 NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
1161 if (treat_as_reject) {
1164 if (go->accept_local && ciaddr1) {
1166 try_.ouraddr = ciaddr1;
1168 if (go->accept_remote && ciaddr2) {
1170 try_.hisaddr = ciaddr2;
1182 NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
1183 if (treat_as_reject) {
1185 }
else if (cilen == CILEN_VJ) {
1186 GETCHAR(cimaxslotindex,
p);
1187 GETCHAR(cicflag,
p);
1188 if (cishort == IPCP_VJ_COMP) {
1190 if (cimaxslotindex < go->maxslotindex)
1191 try_.maxslotindex = cimaxslotindex;
1198 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
1200 try_.vj_protocol = cishort;
1208 NAKCIADDR(CI_ADDR, neg_addr,
1209 if (treat_as_reject) {
1212 }
else if (go->accept_local && ciaddr1) {
1214 try_.ouraddr = ciaddr1;
1219 NAKCIDNS(CI_MS_DNS1, req_dns1,
1220 if (treat_as_reject) {
1223 try_.dnsaddr[0] = cidnsaddr;
1227 NAKCIDNS(CI_MS_DNS2, req_dns2,
1228 if (treat_as_reject) {
1231 try_.dnsaddr[1] = cidnsaddr;
1244 while (
len >= CILEN_VOID) {
1247 if ( cilen < CILEN_VOID || (
len -= cilen) < 0 )
1249 next =
p + cilen - 2;
1253 case CI_COMPRESSTYPE:
1254 if (go->neg_vj ||
no.neg_vj ||
1255 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
1261 if ((!go->neg_addr && go->old_addrs) ||
no.old_addrs
1262 || cilen != CILEN_ADDRS)
1267 if (ciaddr1 && go->accept_local)
1268 try_.ouraddr = ciaddr1;
1271 if (ciaddr2 && go->accept_remote)
1272 try_.hisaddr = ciaddr2;
1276 if (go->neg_addr ||
no.neg_addr || cilen != CILEN_ADDR)
1281 if (ciaddr1 && go->accept_local)
1282 try_.ouraddr = ciaddr1;
1283 if (try_.ouraddr != 0)
1289 if (go->req_dns1 ||
no.req_dns1 || cilen != CILEN_ADDR)
1297 if (go->req_dns2 ||
no.req_dns2 || cilen != CILEN_ADDR)
1308 if (cilen != CILEN_ADDR)
1313 try_.winsaddr[citype == CI_MS_WINS2] = ciaddr1;
1326 if (
f->state != PPP_FSM_OPENED)
1332 IPCPDEBUG((
"ipcp_nakci: received bad Nak!"));
1341static int ipcp_rejci(fsm *
f,
u_char *
p,
int len) {
1342 ppp_pcb *pcb =
f->pcb;
1343 ipcp_options *go = &pcb->ipcp_gotoptions;
1346 u_char cimaxslotindex, ciflag;
1358#define REJCIADDRS(opt, neg, val1, val2) \
1360 (cilen = p[1]) == CILEN_ADDRS && \
1367 cilong = lwip_htonl(l); \
1369 if (cilong != val1) \
1372 cilong = lwip_htonl(l); \
1374 if (cilong != val2) \
1376 try_.old_addrs = 0; \
1380#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
1382 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
1387 GETSHORT(cishort, p); \
1389 if (cishort != val) \
1392 GETCHAR(cimaxslotindex, p); \
1393 if (cimaxslotindex != maxslot) \
1395 GETCHAR(ciflag, p); \
1396 if (ciflag != cflag) \
1403#define REJCIADDR(opt, neg, val) \
1405 (cilen = p[1]) == CILEN_ADDR && \
1412 cilong = lwip_htonl(l); \
1414 if (cilong != val) \
1420#define REJCIDNS(opt, neg, dnsaddr) \
1422 ((cilen = p[1]) == CILEN_ADDR) && \
1429 cilong = lwip_htonl(l); \
1431 if (cilong != dnsaddr) \
1438#define REJCIWINS(opt, addr) \
1440 ((cilen = p[1]) == CILEN_ADDR) && \
1447 cilong = lwip_htonl(l); \
1449 if (cilong != addr) \
1451 try_.winsaddr[opt == CI_MS_WINS2] = 0; \
1455 REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
1456 go->ouraddr, go->hisaddr);
1459 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
1460 go->maxslotindex, go->cflag);
1463 REJCIADDR(CI_ADDR, neg_addr, go->ouraddr);
1466 REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
1468 REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
1472 REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
1474 REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
1485 if (
f->state != PPP_FSM_OPENED)
1490 IPCPDEBUG((
"ipcp_rejci: received bad Reject!"));
1506static int ipcp_reqci(fsm *
f,
u_char *inp,
int *
len,
int reject_if_disagree) {
1507 ppp_pcb *pcb =
f->pcb;
1508 ipcp_options *wo = &pcb->ipcp_wantoptions;
1509 ipcp_options *ho = &pcb->ipcp_hisoptions;
1510 ipcp_options *ao = &pcb->ipcp_allowoptions;
1516 u32_t tl, ciaddr1, ciaddr2;
1523 u_char maxslotindex, cflag;
1532 BZERO(ho,
sizeof(*ho));
1544 IPCPDEBUG((
"ipcp_reqci: bad CI length!"));
1557 if (!ao->old_addrs || ho->neg_addr ||
1558 cilen != CILEN_ADDRS) {
1571 if (ciaddr1 != wo->hisaddr
1572 && (ciaddr1 == 0 || !wo->accept_remote)) {
1574 if (!reject_if_disagree) {
1575 DECPTR(
sizeof(
u32_t),
p);
1579 }
else if (ciaddr1 == 0 && wo->hisaddr == 0) {
1594 if (ciaddr2 != wo->ouraddr) {
1595 if (ciaddr2 == 0 || !wo->accept_local) {
1597 if (!reject_if_disagree) {
1598 DECPTR(
sizeof(
u32_t),
p);
1603 wo->ouraddr = ciaddr2;
1608 ho->hisaddr = ciaddr1;
1609 ho->ouraddr = ciaddr2;
1613 if (!ao->neg_addr || ho->old_addrs ||
1614 cilen != CILEN_ADDR) {
1627 if (ciaddr1 != wo->hisaddr
1628 && (ciaddr1 == 0 || !wo->accept_remote)) {
1630 if (!reject_if_disagree) {
1631 DECPTR(
sizeof(
u32_t),
p);
1635 }
else if (ciaddr1 == 0 && wo->hisaddr == 0) {
1645 ho->hisaddr = ciaddr1;
1652 d = citype == CI_MS_DNS2;
1655 if (ao->dnsaddr[
d] == 0 ||
1656 cilen != CILEN_ADDR) {
1662 DECPTR(
sizeof(
u32_t),
p);
1674 d = citype == CI_MS_WINS2;
1677 if (ao->winsaddr[
d] == 0 ||
1678 cilen != CILEN_ADDR) {
1684 DECPTR(
sizeof(
u32_t),
p);
1693 case CI_COMPRESSTYPE:
1695 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
1699 GETSHORT(cishort,
p);
1701 if (!(cishort == IPCP_VJ_COMP ||
1702 (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
1708 ho->vj_protocol = cishort;
1709 if (cilen == CILEN_VJ) {
1710 GETCHAR(maxslotindex,
p);
1711 if (maxslotindex > ao->maxslotindex) {
1713 if (!reject_if_disagree){
1715 PUTCHAR(ao->maxslotindex,
p);
1719 if (cflag && !ao->cflag) {
1721 if (!reject_if_disagree){
1723 PUTCHAR(wo->cflag,
p);
1726 ho->maxslotindex = maxslotindex;
1730 ho->maxslotindex = MAX_STATES - 1;
1741 if (orc == CONFACK &&
1745 if (orc == CONFNAK) {
1746 if (reject_if_disagree)
1751 if (rc == CONFACK) {
1758 if (orc == CONFREJ &&
1779 if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
1780 wo->req_addr && !reject_if_disagree && !pcb->settings.noremoteip) {
1781 if (rc == CONFACK) {
1786 PUTCHAR(CI_ADDR, ucp);
1787 PUTCHAR(CILEN_ADDR, ucp);
1793 IPCPDEBUG((
"ipcp: returning Configure-%s", CODENAME(rc)));
1808 ipcp_options *wo = &ipcp_wantoptions[0];
1814 if (wo->ouraddr == 0 && !disable_defaultip) {
1820 wo->accept_local = 1;
1824 wo->ouraddr =
local;
1827 ask_for_local = wo->ouraddr != 0 || !disable_defaultip;
1840 ppp_pcb *pcb = &ppp_pcb_list[
u];
1841 ipcp_options *wo = &ipcp_wantoptions[
u];
1843 if (wo->hisaddr == 0 && !pcb->settings.noremoteip) {
1845 wo->hisaddr =
lwip_htonl(0x0a707070 + ifunit);
1846 wo->accept_remote = 1;
1848 if (wo->ouraddr == 0) {
1850 wo->ouraddr =
lwip_htonl(0x0a404040 + ifunit);
1851 wo->accept_local = 1;
1854 if (!sifaddr(pcb, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr)))
1858 if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE))
1861 if (wo->default_route)
1862 if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr,
1863 wo->replace_default_route))
1864 default_route_set[
u] = 1;
1868 if (sifproxyarp(pcb, wo->hisaddr))
1869 proxy_arp_set[
u] = 1;
1872 ppp_notice((
"local IP address %I", wo->ouraddr));
1874 ppp_notice((
"remote IP address %I", wo->hisaddr));
1885static void ipcp_up(fsm *
f) {
1886 ppp_pcb *pcb =
f->pcb;
1888 ipcp_options *ho = &pcb->ipcp_hisoptions;
1889 ipcp_options *go = &pcb->ipcp_gotoptions;
1890 ipcp_options *wo = &pcb->ipcp_wantoptions;
1892 IPCPDEBUG((
"ipcp: up"));
1897 if (!ho->neg_addr && !ho->old_addrs)
1898 ho->hisaddr = wo->hisaddr;
1900 if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs)
1901 && wo->ouraddr != 0) {
1902 ppp_error((
"Peer refused to agree to our IP address"));
1903 ipcp_close(
f->pcb,
"Refused our IP address");
1906 if (go->ouraddr == 0) {
1907 ppp_error((
"Could not determine local IP address"));
1908 ipcp_close(
f->pcb,
"Could not determine local IP address");
1911 if (ho->hisaddr == 0 && !pcb->settings.noremoteip) {
1913 ppp_warn((
"Could not determine remote IP address: defaulting to %I",
1917 script_setenv(
"IPLOCAL", ip_ntoa(go->ouraddr), 0);
1918 if (ho->hisaddr != 0)
1919 script_setenv(
"IPREMOTE", ip_ntoa(ho->hisaddr), 1);
1929 script_setenv(
"DNS1", ip_ntoa(go->dnsaddr[0]), 0);
1931 script_setenv(
"DNS2", ip_ntoa(go->dnsaddr[1]), 0);
1933 if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
1934 sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]);
1936 script_setenv(
"USEPEERDNS",
"1", 0);
1937 create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
1945 if (ho->hisaddr != 0) {
1947 if ((
addr >> IP_CLASSA_NSHIFT) == IP_LOOPBACKNET
1948 || IP_MULTICAST(
addr) || IP_BADCLASS(
addr)
1954#
if PPP_SERVER && PPP_AUTH_SUPPORT
1955 || (pcb->settings.auth_required && wo->hisaddr != ho->hisaddr)
1958 ppp_error((
"Peer is not authorized to use remote address %I", ho->hisaddr));
1959 ipcp_close(pcb,
"Unauthorized remote IP address");
1965 if (ho->hisaddr != 0 && !auth_ip_addr(
f->unit, ho->hisaddr)) {
1966 ppp_error((
"Peer is not authorized to use remote address %I", ho->hisaddr));
1967 ipcp_close(
f->unit,
"Unauthorized remote IP address");
1974 sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex);
1984 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
1985 ipcp_clear_addrs(
f->unit, wo->ouraddr, wo->hisaddr,
1986 wo->replace_default_route);
1987 if (go->ouraddr != wo->ouraddr) {
1988 ppp_warn((
"Local IP address changed to %I", go->ouraddr));
1989 script_setenv(
"OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
1990 wo->ouraddr = go->ouraddr;
1992 script_unsetenv(
"OLDIPLOCAL");
1993 if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
1994 ppp_warn((
"Remote IP address changed to %I", ho->hisaddr));
1995 script_setenv(
"OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
1996 wo->hisaddr = ho->hisaddr;
1998 script_unsetenv(
"OLDIPREMOTE");
2001 mask = get_mask(go->ouraddr);
2002 if (!sifaddr(pcb, go->ouraddr, ho->hisaddr,
mask)) {
2004 ppp_warn((
"Interface configuration failed"));
2006 ipcp_close(
f->unit,
"Interface configuration failed");
2011 if (ipcp_wantoptions[
f->unit].default_route)
2012 if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr,
2013 wo->replace_default_route))
2014 default_route_set[
f->unit] = 1;
2018 if (ho->hisaddr != 0 && ipcp_wantoptions[
f->unit].proxy_arp)
2019 if (sifproxyarp(pcb, ho->hisaddr))
2020 proxy_arp_set[
f->unit] = 1;
2024 demand_rexmit(PPP_IP,go->ouraddr);
2025 sifnpmode(pcb, PPP_IP, NPMODE_PASS);
2033 mask = get_mask(go->ouraddr);
2035#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
2036 if (!sifaddr(pcb, go->ouraddr, ho->hisaddr,
mask)) {
2038 ppp_warn((
"Interface configuration failed"));
2040 ipcp_close(
f->pcb,
"Interface configuration failed");
2048 ppp_warn((
"Interface failed to come up"));
2050 ipcp_close(
f->pcb,
"Interface configuration failed");
2054#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
2055 if (!sifaddr(pcb, go->ouraddr, ho->hisaddr,
mask)) {
2057 ppp_warn((
"Interface configuration failed"));
2059 ipcp_close(
f->unit,
"Interface configuration failed");
2064 sifnpmode(pcb, PPP_IP, NPMODE_PASS);
2069 if (wo->default_route)
2070 if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr,
2071 wo->replace_default_route))
2072 pcb->default_route_set = 1;
2077 if (ho->hisaddr != 0 && wo->proxy_arp)
2078 if (sifproxyarp(pcb, ho->hisaddr))
2079 pcb->proxy_arp_set = 1;
2082 wo->ouraddr = go->ouraddr;
2084 ppp_notice((
"local IP address %I", go->ouraddr));
2085 if (ho->hisaddr != 0)
2086 ppp_notice((
"remote IP address %I", ho->hisaddr));
2089 ppp_notice((
"primary DNS address %I", go->dnsaddr[0]));
2091 ppp_notice((
"secondary DNS address %I", go->dnsaddr[1]));
2095#if PPP_STATS_SUPPORT
2096 reset_link_stats(
f->unit);
2100 pcb->ipcp_is_up = 1;
2103 notify(ip_up_notifier, 0);
2118static void ipcp_down(fsm *
f) {
2119 ppp_pcb *pcb =
f->pcb;
2120 ipcp_options *ho = &pcb->ipcp_hisoptions;
2121 ipcp_options *go = &pcb->ipcp_gotoptions;
2123 IPCPDEBUG((
"ipcp: down"));
2124#if PPP_STATS_SUPPORT
2129 update_link_stats(
f->unit);
2132 notify(ip_down_notifier, 0);
2138 if (pcb->ipcp_is_up) {
2139 pcb->ipcp_is_up = 0;
2140 np_down(pcb, PPP_IP);
2143 sifvjcomp(pcb, 0, 0, 0);
2146#if PPP_STATS_SUPPORT
2158 sifnpmode(pcb, PPP_IP, NPMODE_QUEUE);
2163 sifnpmode(pcb, PPP_IP, NPMODE_DROP);
2166 ipcp_clear_addrs(pcb, go->ouraddr,
2169 cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]);
2179static void ipcp_clear_addrs(ppp_pcb *pcb,
u32_t ouraddr,
u32_t hisaddr,
u8_t replacedefaultroute) {
2183 if (pcb->proxy_arp_set) {
2184 cifproxyarp(pcb, hisaddr);
2185 pcb->proxy_arp_set = 0;
2197 if (!replacedefaultroute && pcb->default_route_set) {
2198 cifdefaultroute(pcb, ouraddr, hisaddr);
2199 pcb->default_route_set = 0;
2202 cifaddr(pcb, ouraddr, hisaddr);
2209static void ipcp_finished(fsm *
f) {
2210 ppp_pcb *pcb =
f->pcb;
2211 if (pcb->ipcp_is_open) {
2212 pcb->ipcp_is_open = 0;
2213 np_finished(pcb, PPP_IP);
2223create_resolv(peerdns1, peerdns2)
2224 u32_t peerdns1, peerdns2;
2234static const char*
const ipcp_codenames[] = {
2235 "ConfReq",
"ConfAck",
"ConfNak",
"ConfRej",
2236 "TermReq",
"TermAck",
"CodeRej"
2239static int ipcp_printpkt(
const u_char *
p,
int plen,
2240 void (*printer) (
void *,
const char *, ...),
void *
arg) {
2248 if (plen < HEADERLEN)
2254 if (len < HEADERLEN || len > plen)
2258 printer(
arg,
" %s", ipcp_codenames[
code-1]);
2260 printer(
arg,
" code=0x%x",
code);
2261 printer(
arg,
" id=0x%x",
id);
2273 if (olen < 2 || olen >
len) {
2281 if (olen == CILEN_ADDRS) {
2290 case CI_COMPRESSTYPE:
2291 if (olen >= CILEN_COMPRESS) {
2293 GETSHORT(cishort,
p);
2294 printer(
arg,
"compress ");
2299 case IPCP_VJ_COMP_OLD:
2300 printer(
arg,
"old-VJ");
2303 printer(
arg,
"0x%x", cishort);
2309 if (olen == CILEN_ADDR) {
2320 printer(
arg,
"ms-dns%d %I", (
code == CI_MS_DNS1? 1: 2),
2345 if (
len > 0 && *
p >=
' ' && *
p < 0x7f) {
2347 ppp_print_string(
p,
len, printer,
arg);
2373#define IP_OFFMASK 0x1fff
2375#define IPPROTO_TCP 6
2377#define TCP_HDRLEN 20
2385#define net_short(x) (((x)[0] << 8) + (x)[1])
2386#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
2387#define get_ipoff(x) net_short((unsigned char *)(x) + 6)
2388#define get_ipproto(x) (((unsigned char *)(x))[9])
2389#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
2390#define get_tcpflags(x) (((unsigned char *)(x))[13])
2393ip_active_pkt(pkt,
len)
2402 if (
len < IP_HDRLEN)
2408 hlen = get_iphl(pkt) * 4;
2409 if (
len < hlen + TCP_HDRLEN)
2412 if ((get_tcpflags(tcp) &
TH_FIN) != 0 &&
len == hlen + get_tcpoff(tcp) * 4)
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
char * strchr(const char *String, int ch)
ULONG WSAAPI inet_addr(IN CONST CHAR FAR *cp)
size_t strlcpy(char *d, const char *s, size_t bufsize)
#define LWIP_ARRAYSIZE(x)
static WCHAR no[MAX_STRING_RESOURCE_LEN]
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
GLboolean GLboolean GLboolean b
GLenum const GLvoid * addr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
#define LWIP_UNUSED_ARG(x)
#define MEMCPY(DST, SRC, BYTES)
const char * optend(char *fmt) const
static unsigned __int64 next