66 #include "lwip/inet.h"
79 static int default_route_set[NUM_PPP];
80 static int cis_received[NUM_PPP];
86 static void ipcp_resetci (
fsm *);
87 static int ipcp_cilen (
fsm *);
88 static void ipcp_addci (
fsm *, u_char *,
int *);
89 static int ipcp_ackci (
fsm *, u_char *,
int);
90 static int ipcp_nakci (
fsm *, u_char *,
int);
91 static int ipcp_rejci (
fsm *, u_char *,
int);
92 static int ipcp_reqci (
fsm *, u_char *,
int *,
int);
93 static void ipcp_up (
fsm *);
94 static void ipcp_down (
fsm *);
95 #if PPP_ADDITIONAL_CALLBACKS
96 static void ipcp_script (
fsm *,
char *);
98 static void ipcp_finished (
fsm *);
125 static void ipcp_init (
int);
126 static void ipcp_open (
int);
127 static void ipcp_close (
int,
char *);
128 static void ipcp_lowerup (
int);
129 static void ipcp_lowerdown (
int);
130 static void ipcp_input (
int, u_char *,
int);
131 static void ipcp_protrej (
int);
143 #if PPP_ADDITIONAL_CALLBACKS
149 #if PPP_ADDITIONAL_CALLBACKS
156 static void ipcp_clear_addrs (
int);
162 #define CILEN_COMPRESS 4
165 #define CILEN_ADDRS 10
168 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \
169 (x) == CONFNAK ? "NAK" : "REJ")
178 fsm *f = &ipcp_fsm[unit];
187 memset(wo, 0,
sizeof(*wo));
188 memset(ao, 0,
sizeof(*ao));
228 ipcp_close(
int unit,
char *reason)
238 ipcp_lowerup(
int unit)
248 ipcp_lowerdown(
int unit)
258 ipcp_input(
int unit, u_char *p,
int len)
270 ipcp_protrej(
int unit)
292 wo->
req_dns1 = ppp_settings.usepeerdns;
293 wo->
req_dns2 = ppp_settings.usepeerdns;
294 ipcp_gotoptions[f->
unit] = *wo;
295 cis_received[f->
unit] = 0;
309 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
310 #define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
311 #define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0)
324 if (cis_received[f->
unit] == 0) {
348 ipcp_addci(
fsm *f, u_char *ucp,
int *lenp)
353 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
355 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
356 if (len >= vjlen) { \
358 PUTCHAR(vjlen, ucp); \
359 PUTSHORT(val, ucp); \
361 PUTCHAR(maxslotindex, ucp); \
362 PUTCHAR(cflag, ucp); \
370 #define ADDCIADDR(opt, neg, old, val1, val2) \
372 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
373 if (len >= addrlen) { \
376 PUTCHAR(addrlen, ucp); \
389 #define ADDCIDNS(opt, neg, addr) \
391 if (len >= CILEN_ADDR) { \
394 PUTCHAR(CILEN_ADDR, ucp); \
425 ipcp_ackci(
fsm *f, u_char *p,
int len)
428 u_short cilen, citype, cishort;
430 u_char cimaxslotindex, cicflag;
438 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
440 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
441 if ((len -= vjlen) < 0) { \
444 GETCHAR(citype, p); \
446 if (cilen != vjlen || \
450 GETSHORT(cishort, p); \
451 if (cishort != val) { \
455 GETCHAR(cimaxslotindex, p); \
456 if (cimaxslotindex != maxslotindex) { \
459 GETCHAR(cicflag, p); \
460 if (cicflag != cflag) { \
466 #define ACKCIADDR(opt, neg, old, val1, val2) \
468 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
470 if ((len -= addrlen) < 0) { \
473 GETCHAR(citype, p); \
475 if (cilen != addrlen || \
481 if (val1 != cilong) { \
487 if (val2 != cilong) { \
493 #define ACKCIDNS(opt, neg, addr) \
496 if ((len -= CILEN_ADDR) < 0) { \
499 GETCHAR(citype, p); \
501 if (cilen != CILEN_ADDR || \
507 if (addr != cilong) { \
545 ipcp_nakci(
fsm *f, u_char *p,
int len)
548 u_char cimaxslotindex, cicflag;
549 u_char citype, cilen, *next;
551 u32_t ciaddr1, ciaddr2, l, cidnsaddr;
555 BZERO(&no,
sizeof(no));
563 #define NAKCIADDR(opt, neg, old, code) \
565 len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
571 ciaddr1 = htonl(l); \
574 ciaddr2 = htonl(l); \
583 #define NAKCIVJ(opt, neg, code) \
585 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
590 GETSHORT(cishort, p); \
595 #define NAKCIDNS(opt, neg, code) \
597 ((cilen = p[1]) == CILEN_ADDR) && \
603 cidnsaddr = htonl(l); \
614 try.ouraddr = ciaddr1;
619 try.hisaddr = ciaddr2;
632 if (cilen == CILEN_VJ) {
633 GETCHAR(cimaxslotindex, p);
637 if (cimaxslotindex < go->maxslotindex) {
638 try.maxslotindex = cimaxslotindex;
649 try.vj_protocol = cishort;
657 try.dnsaddr[0] = cidnsaddr;
662 try.dnsaddr[1] = cidnsaddr;
672 while (len > CILEN_VOID) {
675 if( (len -= cilen) < 0 ) {
678 next = p + cilen - 2;
683 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
690 || cilen != CILEN_ADDRS) {
698 try.ouraddr = ciaddr1;
703 try.hisaddr = ciaddr2;
715 try.ouraddr = ciaddr1;
717 if (
try.ouraddr != 0) {
750 ipcp_rejci(
fsm *f, u_char *p,
int len)
753 u_char cimaxslotindex, ciflag, cilen;
764 #define REJCIADDR(opt, neg, old, val1, val2) \
766 len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
775 if (cilong != val1) { \
782 if (cilong != val2) { \
789 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
791 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
796 GETSHORT(cishort, p); \
798 if (cishort != val) { \
802 GETCHAR(cimaxslotindex, p); \
803 if (cimaxslotindex != maxslot) { \
806 GETCHAR(ciflag, p); \
807 if (ciflag != cflag) { \
814 #define REJCIDNS(opt, neg, dnsaddr) \
816 ((cilen = p[1]) == CILEN_ADDR) && \
825 if (cilong != dnsaddr) { \
869 ipcp_reqci(
fsm *f, u_char *inp,
int *len,
int reject_if_disagree)
878 u_short cilen, citype;
889 u_char maxslotindex, cflag;
892 cis_received[f->
unit] = 1;
897 BZERO(ho,
sizeof(*ho));
925 cilen != CILEN_ADDRS) {
942 if (!reject_if_disagree) {
943 DECPTR(
sizeof(
u32_t), p);
947 }
else if (ciaddr1 == 0 && wo->
hisaddr == 0) {
966 if (!reject_if_disagree) {
967 DECPTR(
sizeof(
u32_t), p);
988 }
else if (cilen != CILEN_ADDR) {
1001 ciaddr1 =
htonl(tl);
1005 if (!reject_if_disagree) {
1006 DECPTR(
sizeof(
u32_t), p);
1011 }
else if (ciaddr1 == 0 && wo->
hisaddr == 0) {
1033 cilen != CILEN_ADDR) {
1042 DECPTR(
sizeof(
u32_t), p);
1058 cilen != CILEN_ADDR) {
1064 DECPTR(
sizeof(
u32_t), p);
1076 }
else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
1081 GETSHORT(cishort, p);
1092 if (cilen == CILEN_VJ) {
1093 GETCHAR(maxslotindex, p);
1097 if (!reject_if_disagree) {
1103 if (cflag && !ao->
cflag) {
1106 if (!reject_if_disagree) {
1108 PUTCHAR(wo->
cflag, p);
1119 "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",
1136 if (reject_if_disagree) {
1158 BCOPY(cip, ucp, cilen);
1173 wo->
req_addr && !reject_if_disagree) {
1180 PUTCHAR(CI_ADDR, ucp);
1181 PUTCHAR(CILEN_ADDR, ucp);
1186 *len = (int)(ucp - inp);
1198 ip_check_options(u_long localAddr)
1206 if (wo->
ouraddr == 0 && !ppp_settings.disable_defaultip) {
1239 ipcp_close(f->
unit,
"Could not determine remote IP address");
1244 ipcp_close(f->
unit,
"Could not determine local IP address");
1248 if (ppp_settings.usepeerdns && (go->
dnsaddr[0] || go->
dnsaddr[1])) {
1258 ipcp_close(f->
unit,
"Unauthorized remote IP address");
1272 ipcp_close(f->
unit,
"Interface configuration failed");
1277 if (!sifup(f->
unit)) {
1279 ipcp_close(f->
unit,
"Interface configuration failed");
1283 sifnpmode(f->
unit, PPP_IP, NPMODE_PASS);
1288 default_route_set[f->
unit] = 1;
1314 sifvjcomp(f->
unit, 0, 0, 0);
1317 ipcp_clear_addrs(f->
unit);
1325 ipcp_clear_addrs(
int unit)
1327 u32_t ouraddr, hisaddr;
1329 ouraddr = ipcp_gotoptions[unit].
ouraddr;
1330 hisaddr = ipcp_hisoptions[unit].
hisaddr;
1331 if (default_route_set[unit]) {
1332 cifdefaultroute(unit, ouraddr, hisaddr);
1333 default_route_set[unit] = 0;
1335 cifaddr(unit, ouraddr, hisaddr);
1343 ipcp_finished(
fsm *f)
1348 #if PPP_ADDITIONAL_CALLBACKS
1350 ipcp_printpkt(u_char *p,
int plen,
void (*printer) (
void *,
char *, ...),
void *arg)
1364 #define IP_HDRLEN 20
1365 #define IP_OFFMASK 0x1fff
1366 #define IPPROTO_TCP 6
1367 #define TCP_HDRLEN 20
1375 #define net_short(x) (((x)[0] << 8) + (x)[1])
1376 #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
1377 #define get_ipoff(x) net_short((unsigned char *)(x) + 6)
1378 #define get_ipproto(x) (((unsigned char *)(x))[9])
1379 #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
1380 #define get_tcpflags(x) (((unsigned char *)(x))[13])
1383 ip_active_pkt(u_char *pkt,
int len)
1390 if (len < IP_HDRLEN) {
1396 if (get_ipproto(pkt) != IPPROTO_TCP) {
1399 hlen = get_iphl(pkt) * 4;
1400 if (len < hlen + TCP_HDRLEN) {
1404 if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) {