| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ipcp.c,v 1.4 2006/06/29 21:50:17 christos Exp $ */ | | 1 | /* $NetBSD: ipcp.c,v 1.5 2010/08/07 20:38:13 christos Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * ipcp.c - PPP IP Control Protocol. | | 4 | * ipcp.c - PPP IP Control Protocol. |
5 | * | | 5 | * |
6 | * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. | | 6 | * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * | | 11 | * |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * | | 14 | * |
| @@ -35,29 +35,30 @@ | | | @@ -35,29 +35,30 @@ |
35 | * | | 35 | * |
36 | * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO | | 36 | * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO |
37 | * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | | 37 | * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
38 | * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE | | 38 | * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE |
39 | * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 39 | * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
40 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | | 40 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN |
41 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | | 41 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING |
42 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 42 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
43 | */ | | 43 | */ |
44 | | | 44 | |
45 | #include <sys/cdefs.h> | | 45 | #include <sys/cdefs.h> |
46 | #ifndef lint | | 46 | #ifndef lint |
47 | #if 0 | | 47 | #if 0 |
| | | 48 | #define RCSID "Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp" |
48 | #define RCSID "Id: ipcp.c,v 1.70 2005/08/25 23:59:34 paulus Exp" | | 49 | #define RCSID "Id: ipcp.c,v 1.70 2005/08/25 23:59:34 paulus Exp" |
49 | #else | | 50 | #else |
50 | __RCSID("$NetBSD: ipcp.c,v 1.4 2006/06/29 21:50:17 christos Exp $"); | | 51 | __RCSID("$NetBSD: ipcp.c,v 1.5 2010/08/07 20:38:13 christos Exp $"); |
51 | #endif | | 52 | #endif |
52 | #endif | | 53 | #endif |
53 | | | 54 | |
54 | /* | | 55 | /* |
55 | * TODO: | | 56 | * TODO: |
56 | */ | | 57 | */ |
57 | | | 58 | |
58 | #include <stdio.h> | | 59 | #include <stdio.h> |
59 | #include <string.h> | | 60 | #include <string.h> |
60 | #include <stdlib.h> | | 61 | #include <stdlib.h> |
61 | #include <netdb.h> | | 62 | #include <netdb.h> |
62 | #include <sys/param.h> | | 63 | #include <sys/param.h> |
63 | #include <sys/types.h> | | 64 | #include <sys/types.h> |
| @@ -73,26 +74,27 @@ __RCSID("$NetBSD: ipcp.c,v 1.4 2006/06/2 | | | @@ -73,26 +74,27 @@ __RCSID("$NetBSD: ipcp.c,v 1.4 2006/06/2 |
73 | #ifdef RCSID | | 74 | #ifdef RCSID |
74 | static const char rcsid[] = RCSID; | | 75 | static const char rcsid[] = RCSID; |
75 | #endif | | 76 | #endif |
76 | | | 77 | |
77 | /* global vars */ | | 78 | /* global vars */ |
78 | ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ | | 79 | ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ |
79 | ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ | | 80 | ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ |
80 | ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ | | 81 | ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ |
81 | ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ | | 82 | ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ |
82 | | | 83 | |
83 | u_int32_t netmask = 0; /* IP netmask to set on interface */ | | 84 | u_int32_t netmask = 0; /* IP netmask to set on interface */ |
84 | | | 85 | |
85 | bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ | | 86 | bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ |
| | | 87 | bool noremoteip = 0; /* Let him have no IP address */ |
86 | | | 88 | |
87 | /* Hook for a plugin to know when IP protocol has come up */ | | 89 | /* Hook for a plugin to know when IP protocol has come up */ |
88 | void (*ip_up_hook) __P((void)) = NULL; | | 90 | void (*ip_up_hook) __P((void)) = NULL; |
89 | | | 91 | |
90 | /* Hook for a plugin to know when IP protocol has come down */ | | 92 | /* Hook for a plugin to know when IP protocol has come down */ |
91 | void (*ip_down_hook) __P((void)) = NULL; | | 93 | void (*ip_down_hook) __P((void)) = NULL; |
92 | | | 94 | |
93 | /* Hook for a plugin to choose the remote IP address */ | | 95 | /* Hook for a plugin to choose the remote IP address */ |
94 | void (*ip_choose_hook) __P((u_int32_t *)) = NULL; | | 96 | void (*ip_choose_hook) __P((u_int32_t *)) = NULL; |
95 | | | 97 | |
96 | /* Notifiers for when IPCP goes up and down */ | | 98 | /* Notifiers for when IPCP goes up and down */ |
97 | struct notifier *ip_up_notifier = NULL; | | 99 | struct notifier *ip_up_notifier = NULL; |
98 | struct notifier *ip_down_notifier = NULL; | | 100 | struct notifier *ip_down_notifier = NULL; |
| @@ -219,26 +221,33 @@ static option_t ipcp_option_list[] = { | | | @@ -219,26 +221,33 @@ static option_t ipcp_option_list[] = { |
219 | | | 221 | |
220 | { "usepeerdns", o_bool, &usepeerdns, | | 222 | { "usepeerdns", o_bool, &usepeerdns, |
221 | "Ask peer for DNS address(es)", 1 }, | | 223 | "Ask peer for DNS address(es)", 1 }, |
222 | | | 224 | |
223 | { "netmask", o_special, (void *)setnetmask, | | 225 | { "netmask", o_special, (void *)setnetmask, |
224 | "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, | | 226 | "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, |
225 | | | 227 | |
226 | { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, | | 228 | { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, |
227 | "Disable old-style IP-Addresses usage", OPT_A2CLR, | | 229 | "Disable old-style IP-Addresses usage", OPT_A2CLR, |
228 | &ipcp_allowoptions[0].old_addrs }, | | 230 | &ipcp_allowoptions[0].old_addrs }, |
229 | { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, | | 231 | { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, |
230 | "Disable IP-Address usage", OPT_A2CLR, | | 232 | "Disable IP-Address usage", OPT_A2CLR, |
231 | &ipcp_allowoptions[0].neg_addr }, | | 233 | &ipcp_allowoptions[0].neg_addr }, |
| | | 234 | #ifdef __linux__ |
| | | 235 | { "noremoteip", o_bool, &noremoteip, |
| | | 236 | "Allow peer to have no IP address", 1 }, |
| | | 237 | #endif |
| | | 238 | { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, |
| | | 239 | "Don't send our IP address to peer", OPT_A2CLR, |
| | | 240 | &ipcp_wantoptions[0].old_addrs}, |
232 | | | 241 | |
233 | { "IP addresses", o_wild, (void *) &setipaddr, | | 242 | { "IP addresses", o_wild, (void *) &setipaddr, |
234 | "set local and remote IP addresses", | | 243 | "set local and remote IP addresses", |
235 | OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, | | 244 | OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, |
236 | | | 245 | |
237 | { NULL } | | 246 | { NULL } |
238 | }; | | 247 | }; |
239 | | | 248 | |
240 | /* | | 249 | /* |
241 | * Protocol entry points from main code. | | 250 | * Protocol entry points from main code. |
242 | */ | | 251 | */ |
243 | static void ipcp_init __P((int)); | | 252 | static void ipcp_init __P((int)); |
244 | static void ipcp_open __P((int)); | | 253 | static void ipcp_open __P((int)); |
| @@ -568,26 +577,34 @@ parse_dotted_ip(p, vp) | | | @@ -568,26 +577,34 @@ parse_dotted_ip(p, vp) |
568 | static void | | 577 | static void |
569 | ipcp_init(unit) | | 578 | ipcp_init(unit) |
570 | int unit; | | 579 | int unit; |
571 | { | | 580 | { |
572 | fsm *f = &ipcp_fsm[unit]; | | 581 | fsm *f = &ipcp_fsm[unit]; |
573 | ipcp_options *wo = &ipcp_wantoptions[unit]; | | 582 | ipcp_options *wo = &ipcp_wantoptions[unit]; |
574 | ipcp_options *ao = &ipcp_allowoptions[unit]; | | 583 | ipcp_options *ao = &ipcp_allowoptions[unit]; |
575 | | | 584 | |
576 | f->unit = unit; | | 585 | f->unit = unit; |
577 | f->protocol = PPP_IPCP; | | 586 | f->protocol = PPP_IPCP; |
578 | f->callbacks = &ipcp_callbacks; | | 587 | f->callbacks = &ipcp_callbacks; |
579 | fsm_init(&ipcp_fsm[unit]); | | 588 | fsm_init(&ipcp_fsm[unit]); |
580 | | | 589 | |
| | | 590 | /* |
| | | 591 | * Some 3G modems use repeated IPCP NAKs as a way of stalling |
| | | 592 | * until they can contact a server on the network, so we increase |
| | | 593 | * the default number of NAKs we accept before we start treating |
| | | 594 | * them as rejects. |
| | | 595 | */ |
| | | 596 | f->maxnakloops = 100; |
| | | 597 | |
581 | memset(wo, 0, sizeof(*wo)); | | 598 | memset(wo, 0, sizeof(*wo)); |
582 | memset(ao, 0, sizeof(*ao)); | | 599 | memset(ao, 0, sizeof(*ao)); |
583 | | | 600 | |
584 | wo->neg_addr = wo->old_addrs = 1; | | 601 | wo->neg_addr = wo->old_addrs = 1; |
585 | wo->neg_vj = 1; | | 602 | wo->neg_vj = 1; |
586 | wo->vj_protocol = IPCP_VJ_COMP; | | 603 | wo->vj_protocol = IPCP_VJ_COMP; |
587 | wo->maxslotindex = MAX_STATES - 1; /* really max index */ | | 604 | wo->maxslotindex = MAX_STATES - 1; /* really max index */ |
588 | wo->cflag = 1; | | 605 | wo->cflag = 1; |
589 | | | 606 | |
590 | | | 607 | |
591 | /* max slots and slot-id compression are currently hardwired in */ | | 608 | /* max slots and slot-id compression are currently hardwired in */ |
592 | /* ppp_if.c to 16 and 1, this needs to be changed (among other */ | | 609 | /* ppp_if.c to 16 and 1, this needs to be changed (among other */ |
593 | /* things) gmc */ | | 610 | /* things) gmc */ |
| @@ -716,49 +733,52 @@ ipcp_resetci(f) | | | @@ -716,49 +733,52 @@ ipcp_resetci(f) |
716 | * Called by fsm_sconfreq, Send Configure Request. | | 733 | * Called by fsm_sconfreq, Send Configure Request. |
717 | */ | | 734 | */ |
718 | static int | | 735 | static int |
719 | ipcp_cilen(f) | | 736 | ipcp_cilen(f) |
720 | fsm *f; | | 737 | fsm *f; |
721 | { | | 738 | { |
722 | ipcp_options *go = &ipcp_gotoptions[f->unit]; | | 739 | ipcp_options *go = &ipcp_gotoptions[f->unit]; |
723 | ipcp_options *wo = &ipcp_wantoptions[f->unit]; | | 740 | ipcp_options *wo = &ipcp_wantoptions[f->unit]; |
724 | ipcp_options *ho = &ipcp_hisoptions[f->unit]; | | 741 | ipcp_options *ho = &ipcp_hisoptions[f->unit]; |
725 | | | 742 | |
726 | #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) | | 743 | #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) |
727 | #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) | | 744 | #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) |
728 | #define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) | | 745 | #define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) |
729 | #define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) | | 746 | #define LENCIDNS(neg) LENCIADDR(neg) |
| | | 747 | #define LENCIWINS(neg) LENCIADDR(neg) |
730 | | | 748 | |
731 | /* | | 749 | /* |
732 | * First see if we want to change our options to the old | | 750 | * First see if we want to change our options to the old |
733 | * forms because we have received old forms from the peer. | | 751 | * forms because we have received old forms from the peer. |
734 | */ | | 752 | */ |
735 | if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) | | 753 | if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) |
736 | go->neg_addr = 0; | | 754 | go->neg_addr = 0; |
737 | if (wo->neg_vj && !go->neg_vj && !go->old_vj) { | | 755 | if (wo->neg_vj && !go->neg_vj && !go->old_vj) { |
738 | /* try an older style of VJ negotiation */ | | 756 | /* try an older style of VJ negotiation */ |
739 | /* use the old style only if the peer did */ | | 757 | /* use the old style only if the peer did */ |
740 | if (ho->neg_vj && ho->old_vj) { | | 758 | if (ho->neg_vj && ho->old_vj) { |
741 | go->neg_vj = 1; | | 759 | go->neg_vj = 1; |
742 | go->old_vj = 1; | | 760 | go->old_vj = 1; |
743 | go->vj_protocol = ho->vj_protocol; | | 761 | go->vj_protocol = ho->vj_protocol; |
744 | } | | 762 | } |
745 | } | | 763 | } |
746 | | | 764 | |
747 | return (LENCIADDRS(!go->neg_addr && go->old_addrs) + | | 765 | return (LENCIADDRS(!go->neg_addr && go->old_addrs) + |
748 | LENCIVJ(go->neg_vj, go->old_vj) + | | 766 | LENCIVJ(go->neg_vj, go->old_vj) + |
749 | LENCIADDR(go->neg_addr) + | | 767 | LENCIADDR(go->neg_addr) + |
750 | LENCIDNS(go->req_dns1) + | | 768 | LENCIDNS(go->req_dns1) + |
751 | LENCIDNS(go->req_dns2)) ; | | 769 | LENCIDNS(go->req_dns2) + |
| | | 770 | LENCIWINS(go->winsaddr[0]) + |
| | | 771 | LENCIWINS(go->winsaddr[1])) ; |
752 | } | | 772 | } |
753 | | | 773 | |
754 | | | 774 | |
755 | /* | | 775 | /* |
756 | * ipcp_addci - Add our desired CIs to a packet. | | 776 | * ipcp_addci - Add our desired CIs to a packet. |
757 | * Called by fsm_sconfreq, Send Configure Request. | | 777 | * Called by fsm_sconfreq, Send Configure Request. |
758 | */ | | 778 | */ |
759 | static void | | 779 | static void |
760 | ipcp_addci(f, ucp, lenp) | | 780 | ipcp_addci(f, ucp, lenp) |
761 | fsm *f; | | 781 | fsm *f; |
762 | u_char *ucp; | | 782 | u_char *ucp; |
763 | int *lenp; | | 783 | int *lenp; |
764 | { | | 784 | { |
| @@ -812,38 +832,55 @@ ipcp_addci(f, ucp, lenp) | | | @@ -812,38 +832,55 @@ ipcp_addci(f, ucp, lenp) |
812 | #define ADDCIDNS(opt, neg, addr) \ | | 832 | #define ADDCIDNS(opt, neg, addr) \ |
813 | if (neg) { \ | | 833 | if (neg) { \ |
814 | if (len >= CILEN_ADDR) { \ | | 834 | if (len >= CILEN_ADDR) { \ |
815 | u_int32_t l; \ | | 835 | u_int32_t l; \ |
816 | PUTCHAR(opt, ucp); \ | | 836 | PUTCHAR(opt, ucp); \ |
817 | PUTCHAR(CILEN_ADDR, ucp); \ | | 837 | PUTCHAR(CILEN_ADDR, ucp); \ |
818 | l = ntohl(addr); \ | | 838 | l = ntohl(addr); \ |
819 | PUTLONG(l, ucp); \ | | 839 | PUTLONG(l, ucp); \ |
820 | len -= CILEN_ADDR; \ | | 840 | len -= CILEN_ADDR; \ |
821 | } else \ | | 841 | } else \ |
822 | neg = 0; \ | | 842 | neg = 0; \ |
823 | } | | 843 | } |
824 | | | 844 | |
| | | 845 | #define ADDCIWINS(opt, addr) \ |
| | | 846 | if (addr) { \ |
| | | 847 | if (len >= CILEN_ADDR) { \ |
| | | 848 | u_int32_t l; \ |
| | | 849 | PUTCHAR(opt, ucp); \ |
| | | 850 | PUTCHAR(CILEN_ADDR, ucp); \ |
| | | 851 | l = ntohl(addr); \ |
| | | 852 | PUTLONG(l, ucp); \ |
| | | 853 | len -= CILEN_ADDR; \ |
| | | 854 | } else \ |
| | | 855 | addr = 0; \ |
| | | 856 | } |
| | | 857 | |
825 | ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, | | 858 | ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, |
826 | go->hisaddr); | | 859 | go->hisaddr); |
827 | | | 860 | |
828 | ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, | | 861 | ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, |
829 | go->maxslotindex, go->cflag); | | 862 | go->maxslotindex, go->cflag); |
830 | | | 863 | |
831 | ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); | | 864 | ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); |
832 | | | 865 | |
833 | ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); | | 866 | ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); |
834 | | | 867 | |
835 | ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); | | 868 | ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); |
836 | | | 869 | |
| | | 870 | ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]); |
| | | 871 | |
| | | 872 | ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]); |
| | | 873 | |
837 | *lenp -= len; | | 874 | *lenp -= len; |
838 | } | | 875 | } |
839 | | | 876 | |
840 | | | 877 | |
841 | /* | | 878 | /* |
842 | * ipcp_ackci - Ack our CIs. | | 879 | * ipcp_ackci - Ack our CIs. |
843 | * Called by fsm_rconfack, Receive Configure ACK. | | 880 | * Called by fsm_rconfack, Receive Configure ACK. |
844 | * | | 881 | * |
845 | * Returns: | | 882 | * Returns: |
846 | * 0 - Ack was bad. | | 883 | * 0 - Ack was bad. |
847 | * 1 - Ack was good. | | 884 | * 1 - Ack was good. |
848 | */ | | 885 | */ |
849 | static int | | 886 | static int |
| @@ -1118,26 +1155,28 @@ ipcp_nakci(f, p, len, treat_as_reject) | | | @@ -1118,26 +1155,28 @@ ipcp_nakci(f, p, len, treat_as_reject) |
1118 | NAKCIDNS(CI_MS_DNS2, req_dns2, | | 1155 | NAKCIDNS(CI_MS_DNS2, req_dns2, |
1119 | if (treat_as_reject) { | | 1156 | if (treat_as_reject) { |
1120 | try.req_dns2 = 0; | | 1157 | try.req_dns2 = 0; |
1121 | } else { | | 1158 | } else { |
1122 | try.dnsaddr[1] = cidnsaddr; | | 1159 | try.dnsaddr[1] = cidnsaddr; |
1123 | } | | 1160 | } |
1124 | ); | | 1161 | ); |
1125 | | | 1162 | |
1126 | /* | | 1163 | /* |
1127 | * There may be remaining CIs, if the peer is requesting negotiation | | 1164 | * There may be remaining CIs, if the peer is requesting negotiation |
1128 | * on an option that we didn't include in our request packet. | | 1165 | * on an option that we didn't include in our request packet. |
1129 | * If they want to negotiate about IP addresses, we comply. | | 1166 | * If they want to negotiate about IP addresses, we comply. |
1130 | * If they want us to ask for compression, we refuse. | | 1167 | * If they want us to ask for compression, we refuse. |
| | | 1168 | * If they want us to ask for ms-dns, we do that, since some |
| | | 1169 | * peers get huffy if we don't. |
1131 | */ | | 1170 | */ |
1132 | while (len >= CILEN_VOID) { | | 1171 | while (len >= CILEN_VOID) { |
1133 | GETCHAR(citype, p); | | 1172 | GETCHAR(citype, p); |
1134 | GETCHAR(cilen, p); | | 1173 | GETCHAR(cilen, p); |
1135 | if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) | | 1174 | if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) |
1136 | goto bad; | | 1175 | goto bad; |
1137 | next = p + cilen - 2; | | 1176 | next = p + cilen - 2; |
1138 | | | 1177 | |
1139 | switch (citype) { | | 1178 | switch (citype) { |
1140 | case CI_COMPRESSTYPE: | | 1179 | case CI_COMPRESSTYPE: |
1141 | if (go->neg_vj || no.neg_vj || | | 1180 | if (go->neg_vj || no.neg_vj || |
1142 | (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) | | 1181 | (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) |
1143 | goto bad; | | 1182 | goto bad; |
| @@ -1160,26 +1199,51 @@ ipcp_nakci(f, p, len, treat_as_reject) | | | @@ -1160,26 +1199,51 @@ ipcp_nakci(f, p, len, treat_as_reject) |
1160 | break; | | 1199 | break; |
1161 | case CI_ADDR: | | 1200 | case CI_ADDR: |
1162 | if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) | | 1201 | if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) |
1163 | goto bad; | | 1202 | goto bad; |
1164 | try.old_addrs = 0; | | 1203 | try.old_addrs = 0; |
1165 | GETLONG(l, p); | | 1204 | GETLONG(l, p); |
1166 | ciaddr1 = htonl(l); | | 1205 | ciaddr1 = htonl(l); |
1167 | if (ciaddr1 && go->accept_local) | | 1206 | if (ciaddr1 && go->accept_local) |
1168 | try.ouraddr = ciaddr1; | | 1207 | try.ouraddr = ciaddr1; |
1169 | if (try.ouraddr != 0) | | 1208 | if (try.ouraddr != 0) |
1170 | try.neg_addr = 1; | | 1209 | try.neg_addr = 1; |
1171 | no.neg_addr = 1; | | 1210 | no.neg_addr = 1; |
1172 | break; | | 1211 | break; |
| | | 1212 | case CI_MS_DNS1: |
| | | 1213 | if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) |
| | | 1214 | goto bad; |
| | | 1215 | GETLONG(l, p); |
| | | 1216 | try.dnsaddr[0] = htonl(l); |
| | | 1217 | try.req_dns1 = 1; |
| | | 1218 | no.req_dns1 = 1; |
| | | 1219 | break; |
| | | 1220 | case CI_MS_DNS2: |
| | | 1221 | if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) |
| | | 1222 | goto bad; |
| | | 1223 | GETLONG(l, p); |
| | | 1224 | try.dnsaddr[1] = htonl(l); |
| | | 1225 | try.req_dns2 = 1; |
| | | 1226 | no.req_dns2 = 1; |
| | | 1227 | break; |
| | | 1228 | case CI_MS_WINS1: |
| | | 1229 | case CI_MS_WINS2: |
| | | 1230 | if (cilen != CILEN_ADDR) |
| | | 1231 | goto bad; |
| | | 1232 | GETLONG(l, p); |
| | | 1233 | ciaddr1 = htonl(l); |
| | | 1234 | if (ciaddr1) |
| | | 1235 | try.winsaddr[citype == CI_MS_WINS2] = ciaddr1; |
| | | 1236 | break; |
1173 | } | | 1237 | } |
1174 | p = next; | | 1238 | p = next; |
1175 | } | | 1239 | } |
1176 | | | 1240 | |
1177 | /* | | 1241 | /* |
1178 | * OK, the Nak is good. Now we can update state. | | 1242 | * OK, the Nak is good. Now we can update state. |
1179 | * If there are any remaining options, we ignore them. | | 1243 | * If there are any remaining options, we ignore them. |
1180 | */ | | 1244 | */ |
1181 | if (f->state != OPENED) | | 1245 | if (f->state != OPENED) |
1182 | *go = try; | | 1246 | *go = try; |
1183 | | | 1247 | |
1184 | return 1; | | 1248 | return 1; |
1185 | | | 1249 | |
| @@ -1276,39 +1340,58 @@ ipcp_rejci(f, p, len) | | | @@ -1276,39 +1340,58 @@ ipcp_rejci(f, p, len) |
1276 | len >= cilen && \ | | 1340 | len >= cilen && \ |
1277 | p[0] == opt) { \ | | 1341 | p[0] == opt) { \ |
1278 | u_int32_t l; \ | | 1342 | u_int32_t l; \ |
1279 | len -= cilen; \ | | 1343 | len -= cilen; \ |
1280 | INCPTR(2, p); \ | | 1344 | INCPTR(2, p); \ |
1281 | GETLONG(l, p); \ | | 1345 | GETLONG(l, p); \ |
1282 | cilong = htonl(l); \ | | 1346 | cilong = htonl(l); \ |
1283 | /* Check rejected value. */ \ | | 1347 | /* Check rejected value. */ \ |
1284 | if (cilong != dnsaddr) \ | | 1348 | if (cilong != dnsaddr) \ |
1285 | goto bad; \ | | 1349 | goto bad; \ |
1286 | try.neg = 0; \ | | 1350 | try.neg = 0; \ |
1287 | } | | 1351 | } |
1288 | | | 1352 | |
| | | 1353 | #define REJCIWINS(opt, addr) \ |
| | | 1354 | if (addr && \ |
| | | 1355 | ((cilen = p[1]) == CILEN_ADDR) && \ |
| | | 1356 | len >= cilen && \ |
| | | 1357 | p[0] == opt) { \ |
| | | 1358 | u_int32_t l; \ |
| | | 1359 | len -= cilen; \ |
| | | 1360 | INCPTR(2, p); \ |
| | | 1361 | GETLONG(l, p); \ |
| | | 1362 | cilong = htonl(l); \ |
| | | 1363 | /* Check rejected value. */ \ |
| | | 1364 | if (cilong != addr) \ |
| | | 1365 | goto bad; \ |
| | | 1366 | try.winsaddr[opt == CI_MS_WINS2] = 0; \ |
| | | 1367 | } |
1289 | | | 1368 | |
1290 | REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, | | 1369 | REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, |
1291 | go->ouraddr, go->hisaddr); | | 1370 | go->ouraddr, go->hisaddr); |
1292 | | | 1371 | |
1293 | REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, | | 1372 | REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, |
1294 | go->maxslotindex, go->cflag); | | 1373 | go->maxslotindex, go->cflag); |
1295 | | | 1374 | |
1296 | REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); | | 1375 | REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); |
1297 | | | 1376 | |
1298 | REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); | | 1377 | REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); |
1299 | | | 1378 | |
1300 | REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); | | 1379 | REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); |
1301 | | | 1380 | |
| | | 1381 | REJCIWINS(CI_MS_WINS1, go->winsaddr[0]); |
| | | 1382 | |
| | | 1383 | REJCIWINS(CI_MS_WINS2, go->winsaddr[1]); |
| | | 1384 | |
1302 | /* | | 1385 | /* |
1303 | * If there are any remaining CIs, then this packet is bad. | | 1386 | * If there are any remaining CIs, then this packet is bad. |
1304 | */ | | 1387 | */ |
1305 | if (len != 0) | | 1388 | if (len != 0) |
1306 | goto bad; | | 1389 | goto bad; |
1307 | /* | | 1390 | /* |
1308 | * Now we can update state. | | 1391 | * Now we can update state. |
1309 | */ | | 1392 | */ |
1310 | if (f->state != OPENED) | | 1393 | if (f->state != OPENED) |
1311 | *go = try; | | 1394 | *go = try; |
1312 | return 1; | | 1395 | return 1; |
1313 | | | 1396 | |
1314 | bad: | | 1397 | bad: |
| @@ -1582,27 +1665,27 @@ endswitch: | | | @@ -1582,27 +1665,27 @@ endswitch: |
1582 | | | 1665 | |
1583 | /* Update output pointer */ | | 1666 | /* Update output pointer */ |
1584 | INCPTR(cilen, ucp); | | 1667 | INCPTR(cilen, ucp); |
1585 | } | | 1668 | } |
1586 | | | 1669 | |
1587 | /* | | 1670 | /* |
1588 | * If we aren't rejecting this packet, and we want to negotiate | | 1671 | * If we aren't rejecting this packet, and we want to negotiate |
1589 | * their address, and they didn't send their address, then we | | 1672 | * their address, and they didn't send their address, then we |
1590 | * send a NAK with a CI_ADDR option appended. We assume the | | 1673 | * send a NAK with a CI_ADDR option appended. We assume the |
1591 | * input buffer is long enough that we can append the extra | | 1674 | * input buffer is long enough that we can append the extra |
1592 | * option safely. | | 1675 | * option safely. |
1593 | */ | | 1676 | */ |
1594 | if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && | | 1677 | if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && |
1595 | wo->req_addr && !reject_if_disagree) { | | 1678 | wo->req_addr && !reject_if_disagree && !noremoteip) { |
1596 | if (rc == CONFACK) { | | 1679 | if (rc == CONFACK) { |
1597 | rc = CONFNAK; | | 1680 | rc = CONFNAK; |
1598 | ucp = inp; /* reset pointer */ | | 1681 | ucp = inp; /* reset pointer */ |
1599 | wo->req_addr = 0; /* don't ask again */ | | 1682 | wo->req_addr = 0; /* don't ask again */ |
1600 | } | | 1683 | } |
1601 | PUTCHAR(CI_ADDR, ucp); | | 1684 | PUTCHAR(CI_ADDR, ucp); |
1602 | PUTCHAR(CILEN_ADDR, ucp); | | 1685 | PUTCHAR(CILEN_ADDR, ucp); |
1603 | tl = ntohl(wo->hisaddr); | | 1686 | tl = ntohl(wo->hisaddr); |
1604 | PUTLONG(tl, ucp); | | 1687 | PUTLONG(tl, ucp); |
1605 | } | | 1688 | } |
1606 | | | 1689 | |
1607 | *len = ucp - inp; /* Compute output length */ | | 1690 | *len = ucp - inp; /* Compute output length */ |
1608 | IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); | | 1691 | IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); |
| @@ -1642,53 +1725,54 @@ ip_check_options() | | | @@ -1642,53 +1725,54 @@ ip_check_options() |
1642 | } | | 1725 | } |
1643 | | | 1726 | |
1644 | | | 1727 | |
1645 | /* | | 1728 | /* |
1646 | * ip_demand_conf - configure the interface as though | | 1729 | * ip_demand_conf - configure the interface as though |
1647 | * IPCP were up, for use with dial-on-demand. | | 1730 | * IPCP were up, for use with dial-on-demand. |
1648 | */ | | 1731 | */ |
1649 | static int | | 1732 | static int |
1650 | ip_demand_conf(u) | | 1733 | ip_demand_conf(u) |
1651 | int u; | | 1734 | int u; |
1652 | { | | 1735 | { |
1653 | ipcp_options *wo = &ipcp_wantoptions[u]; | | 1736 | ipcp_options *wo = &ipcp_wantoptions[u]; |
1654 | | | 1737 | |
1655 | if (wo->hisaddr == 0) { | | 1738 | if (wo->hisaddr == 0 && !noremoteip) { |
1656 | /* make up an arbitrary address for the peer */ | | 1739 | /* make up an arbitrary address for the peer */ |
1657 | wo->hisaddr = htonl(0x0a707070 + ifunit); | | 1740 | wo->hisaddr = htonl(0x0a707070 + ifunit); |
1658 | wo->accept_remote = 1; | | 1741 | wo->accept_remote = 1; |
1659 | } | | 1742 | } |
1660 | if (wo->ouraddr == 0) { | | 1743 | if (wo->ouraddr == 0) { |
1661 | /* make up an arbitrary address for us */ | | 1744 | /* make up an arbitrary address for us */ |
1662 | wo->ouraddr = htonl(0x0a404040 + ifunit); | | 1745 | wo->ouraddr = htonl(0x0a404040 + ifunit); |
1663 | wo->accept_local = 1; | | 1746 | wo->accept_local = 1; |
1664 | ask_for_local = 0; /* don't tell the peer this address */ | | 1747 | ask_for_local = 0; /* don't tell the peer this address */ |
1665 | } | | 1748 | } |
1666 | if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) | | 1749 | if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) |
1667 | return 0; | | 1750 | return 0; |
1668 | ipcp_script(_PATH_IPPREUP, 1); | | 1751 | ipcp_script(_PATH_IPPREUP, 1); |
1669 | if (!sifup(u)) | | 1752 | if (!sifup(u)) |
1670 | return 0; | | 1753 | return 0; |
1671 | if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) | | 1754 | if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) |
1672 | return 0; | | 1755 | return 0; |
1673 | if (wo->default_route) | | 1756 | if (wo->default_route) |
1674 | if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) | | 1757 | if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) |
1675 | default_route_set[u] = 1; | | 1758 | default_route_set[u] = 1; |
1676 | if (wo->proxy_arp) | | 1759 | if (wo->proxy_arp) |
1677 | if (sifproxyarp(u, wo->hisaddr)) | | 1760 | if (sifproxyarp(u, wo->hisaddr)) |
1678 | proxy_arp_set[u] = 1; | | 1761 | proxy_arp_set[u] = 1; |
1679 | | | 1762 | |
1680 | notice("local IP address %I", wo->ouraddr); | | 1763 | notice("local IP address %I", wo->ouraddr); |
1681 | notice("remote IP address %I", wo->hisaddr); | | 1764 | if (wo->hisaddr) |
| | | 1765 | notice("remote IP address %I", wo->hisaddr); |
1682 | | | 1766 | |
1683 | return 1; | | 1767 | return 1; |
1684 | } | | 1768 | } |
1685 | | | 1769 | |
1686 | | | 1770 | |
1687 | /* | | 1771 | /* |
1688 | * ipcp_up - IPCP has come UP. | | 1772 | * ipcp_up - IPCP has come UP. |
1689 | * | | 1773 | * |
1690 | * Configure the IP network interface appropriately and bring it up. | | 1774 | * Configure the IP network interface appropriately and bring it up. |
1691 | */ | | 1775 | */ |
1692 | static void | | 1776 | static void |
1693 | ipcp_up(f) | | 1777 | ipcp_up(f) |
1694 | fsm *f; | | 1778 | fsm *f; |
| @@ -1707,87 +1791,92 @@ ipcp_up(f) | | | @@ -1707,87 +1791,92 @@ ipcp_up(f) |
1707 | ho->hisaddr = wo->hisaddr; | | 1791 | ho->hisaddr = wo->hisaddr; |
1708 | | | 1792 | |
1709 | if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) | | 1793 | if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) |
1710 | && wo->ouraddr != 0) { | | 1794 | && wo->ouraddr != 0) { |
1711 | error("Peer refused to agree to our IP address"); | | 1795 | error("Peer refused to agree to our IP address"); |
1712 | ipcp_close(f->unit, "Refused our IP address"); | | 1796 | ipcp_close(f->unit, "Refused our IP address"); |
1713 | return; | | 1797 | return; |
1714 | } | | 1798 | } |
1715 | if (go->ouraddr == 0) { | | 1799 | if (go->ouraddr == 0) { |
1716 | error("Could not determine local IP address"); | | 1800 | error("Could not determine local IP address"); |
1717 | ipcp_close(f->unit, "Could not determine local IP address"); | | 1801 | ipcp_close(f->unit, "Could not determine local IP address"); |
1718 | return; | | 1802 | return; |
1719 | } | | 1803 | } |
1720 | if (ho->hisaddr == 0) { | | 1804 | if (ho->hisaddr == 0 && !noremoteip) { |
1721 | ho->hisaddr = htonl(0x0a404040 + ifunit); | | 1805 | ho->hisaddr = htonl(0x0a404040 + ifunit); |
1722 | warn("Could not determine remote IP address: defaulting to %I", | | 1806 | warn("Could not determine remote IP address: defaulting to %I", |
1723 | ho->hisaddr); | | 1807 | ho->hisaddr); |
1724 | } | | 1808 | } |
1725 | script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); | | 1809 | script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); |
1726 | script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); | | 1810 | if (ho->hisaddr != 0) |
| | | 1811 | script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); |
1727 | | | 1812 | |
| | | 1813 | if (!go->req_dns1) |
| | | 1814 | go->dnsaddr[0] = 0; |
| | | 1815 | if (!go->req_dns2) |
| | | 1816 | go->dnsaddr[1] = 0; |
1728 | if (go->dnsaddr[0]) | | 1817 | if (go->dnsaddr[0]) |
1729 | script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); | | 1818 | script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); |
1730 | if (go->dnsaddr[1]) | | 1819 | if (go->dnsaddr[1]) |
1731 | script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); | | 1820 | script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); |
1732 | if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { | | 1821 | if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { |
1733 | script_setenv("USEPEERDNS", "1", 0); | | 1822 | script_setenv("USEPEERDNS", "1", 0); |
1734 | create_resolv(go->dnsaddr[0], go->dnsaddr[1]); | | 1823 | create_resolv(go->dnsaddr[0], go->dnsaddr[1]); |
1735 | } | | 1824 | } |
1736 | | | 1825 | |
1737 | /* | | 1826 | /* |
1738 | * Check that the peer is allowed to use the IP address it wants. | | 1827 | * Check that the peer is allowed to use the IP address it wants. |
1739 | */ | | 1828 | */ |
1740 | if (!auth_ip_addr(f->unit, ho->hisaddr)) { | | 1829 | if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { |
1741 | error("Peer is not authorized to use remote address %I", ho->hisaddr); | | 1830 | error("Peer is not authorized to use remote address %I", ho->hisaddr); |
1742 | ipcp_close(f->unit, "Unauthorized remote IP address"); | | 1831 | ipcp_close(f->unit, "Unauthorized remote IP address"); |
1743 | return; | | 1832 | return; |
1744 | } | | 1833 | } |
1745 | | | 1834 | |
1746 | /* set tcp compression */ | | 1835 | /* set tcp compression */ |
1747 | sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); | | 1836 | sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); |
1748 | | | 1837 | |
1749 | /* | | 1838 | /* |
1750 | * If we are doing dial-on-demand, the interface is already | | 1839 | * If we are doing dial-on-demand, the interface is already |
1751 | * configured, so we put out any saved-up packets, then set the | | 1840 | * configured, so we put out any saved-up packets, then set the |
1752 | * interface to pass IP packets. | | 1841 | * interface to pass IP packets. |
1753 | */ | | 1842 | */ |
1754 | if (demand) { | | 1843 | if (demand) { |
1755 | if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { | | 1844 | if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { |
1756 | ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); | | 1845 | ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); |
1757 | if (go->ouraddr != wo->ouraddr) { | | 1846 | if (go->ouraddr != wo->ouraddr) { |
1758 | warn("Local IP address changed to %I", go->ouraddr); | | 1847 | warn("Local IP address changed to %I", go->ouraddr); |
1759 | script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); | | 1848 | script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); |
1760 | wo->ouraddr = go->ouraddr; | | 1849 | wo->ouraddr = go->ouraddr; |
1761 | } else | | 1850 | } else |
1762 | script_unsetenv("OLDIPLOCAL"); | | 1851 | script_unsetenv("OLDIPLOCAL"); |
1763 | if (ho->hisaddr != wo->hisaddr) { | | 1852 | if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { |
1764 | warn("Remote IP address changed to %I", ho->hisaddr); | | 1853 | warn("Remote IP address changed to %I", ho->hisaddr); |
1765 | script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); | | 1854 | script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); |
1766 | wo->hisaddr = ho->hisaddr; | | 1855 | wo->hisaddr = ho->hisaddr; |
1767 | } else | | 1856 | } else |
1768 | script_unsetenv("OLDIPREMOTE"); | | 1857 | script_unsetenv("OLDIPREMOTE"); |
1769 | | | 1858 | |
1770 | /* Set the interface to the new addresses */ | | 1859 | /* Set the interface to the new addresses */ |
1771 | mask = GetMask(go->ouraddr); | | 1860 | mask = GetMask(go->ouraddr); |
1772 | if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { | | 1861 | if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { |
1773 | if (debug) | | 1862 | if (debug) |
1774 | warn("Interface configuration failed"); | | 1863 | warn("Interface configuration failed"); |
1775 | ipcp_close(f->unit, "Interface configuration failed"); | | 1864 | ipcp_close(f->unit, "Interface configuration failed"); |
1776 | return; | | 1865 | return; |
1777 | } | | 1866 | } |
1778 | | | 1867 | |
1779 | /* assign a default route through the interface if required */ | | 1868 | /* assign a default route through the interface if required */ |
1780 | if (ipcp_wantoptions[f->unit].default_route) | | 1869 | if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].default_route) |
1781 | if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) | | 1870 | if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) |
1782 | default_route_set[f->unit] = 1; | | 1871 | default_route_set[f->unit] = 1; |
1783 | | | 1872 | |
1784 | /* Make a proxy ARP entry if requested. */ | | 1873 | /* Make a proxy ARP entry if requested. */ |
1785 | if (ipcp_wantoptions[f->unit].proxy_arp) | | 1874 | if (ipcp_wantoptions[f->unit].proxy_arp) |
1786 | if (sifproxyarp(f->unit, ho->hisaddr)) | | 1875 | if (sifproxyarp(f->unit, ho->hisaddr)) |
1787 | proxy_arp_set[f->unit] = 1; | | 1876 | proxy_arp_set[f->unit] = 1; |
1788 | | | 1877 | |
1789 | } | | 1878 | } |
1790 | demand_rexmit(PPP_IP); | | 1879 | demand_rexmit(PPP_IP); |
1791 | sifnpmode(f->unit, PPP_IP, NPMODE_PASS); | | 1880 | sifnpmode(f->unit, PPP_IP, NPMODE_PASS); |
1792 | | | 1881 | |
1793 | } else { | | 1882 | } else { |
| @@ -1822,34 +1911,35 @@ ipcp_up(f) | | | @@ -1822,34 +1911,35 @@ ipcp_up(f) |
1822 | warn("Interface configuration failed"); | | 1911 | warn("Interface configuration failed"); |
1823 | ipcp_close(f->unit, "Interface configuration failed"); | | 1912 | ipcp_close(f->unit, "Interface configuration failed"); |
1824 | return; | | 1913 | return; |
1825 | } | | 1914 | } |
1826 | #endif | | 1915 | #endif |
1827 | sifnpmode(f->unit, PPP_IP, NPMODE_PASS); | | 1916 | sifnpmode(f->unit, PPP_IP, NPMODE_PASS); |
1828 | | | 1917 | |
1829 | /* assign a default route through the interface if required */ | | 1918 | /* assign a default route through the interface if required */ |
1830 | if (ipcp_wantoptions[f->unit].default_route) | | 1919 | if (ipcp_wantoptions[f->unit].default_route) |
1831 | if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) | | 1920 | if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) |
1832 | default_route_set[f->unit] = 1; | | 1921 | default_route_set[f->unit] = 1; |
1833 | | | 1922 | |
1834 | /* Make a proxy ARP entry if requested. */ | | 1923 | /* Make a proxy ARP entry if requested. */ |
1835 | if (ipcp_wantoptions[f->unit].proxy_arp) | | 1924 | if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) |
1836 | if (sifproxyarp(f->unit, ho->hisaddr)) | | 1925 | if (sifproxyarp(f->unit, ho->hisaddr)) |
1837 | proxy_arp_set[f->unit] = 1; | | 1926 | proxy_arp_set[f->unit] = 1; |
1838 | | | 1927 | |
1839 | ipcp_wantoptions[0].ouraddr = go->ouraddr; | | 1928 | ipcp_wantoptions[0].ouraddr = go->ouraddr; |
1840 | | | 1929 | |
1841 | notice("local IP address %I", go->ouraddr); | | 1930 | notice("local IP address %I", go->ouraddr); |
1842 | notice("remote IP address %I", ho->hisaddr); | | 1931 | if (ho->hisaddr != 0) |
| | | 1932 | notice("remote IP address %I", ho->hisaddr); |
1843 | if (go->dnsaddr[0]) | | 1933 | if (go->dnsaddr[0]) |
1844 | notice("primary DNS address %I", go->dnsaddr[0]); | | 1934 | notice("primary DNS address %I", go->dnsaddr[0]); |
1845 | if (go->dnsaddr[1]) | | 1935 | if (go->dnsaddr[1]) |
1846 | notice("secondary DNS address %I", go->dnsaddr[1]); | | 1936 | notice("secondary DNS address %I", go->dnsaddr[1]); |
1847 | } | | 1937 | } |
1848 | | | 1938 | |
1849 | reset_link_stats(f->unit); | | 1939 | reset_link_stats(f->unit); |
1850 | | | 1940 | |
1851 | np_up(f->unit, PPP_IP); | | 1941 | np_up(f->unit, PPP_IP); |
1852 | ipcp_is_up = 1; | | 1942 | ipcp_is_up = 1; |
1853 | | | 1943 | |
1854 | notify(ip_up_notifier, 0); | | 1944 | notify(ip_up_notifier, 0); |
1855 | if (ip_up_hook) | | 1945 | if (ip_up_hook) |
| @@ -2115,27 +2205,27 @@ ipcp_printpkt(p, plen, printer, arg) | | | @@ -2115,27 +2205,27 @@ ipcp_printpkt(p, plen, printer, arg) |
2115 | } | | 2205 | } |
2116 | break; | | 2206 | break; |
2117 | case CI_ADDR: | | 2207 | case CI_ADDR: |
2118 | if (olen == CILEN_ADDR) { | | 2208 | if (olen == CILEN_ADDR) { |
2119 | p += 2; | | 2209 | p += 2; |
2120 | GETLONG(cilong, p); | | 2210 | GETLONG(cilong, p); |
2121 | printer(arg, "addr %I", htonl(cilong)); | | 2211 | printer(arg, "addr %I", htonl(cilong)); |
2122 | } | | 2212 | } |
2123 | break; | | 2213 | break; |
2124 | case CI_MS_DNS1: | | 2214 | case CI_MS_DNS1: |
2125 | case CI_MS_DNS2: | | 2215 | case CI_MS_DNS2: |
2126 | p += 2; | | 2216 | p += 2; |
2127 | GETLONG(cilong, p); | | 2217 | GETLONG(cilong, p); |
2128 | printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1, | | 2218 | printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2), |
2129 | htonl(cilong)); | | 2219 | htonl(cilong)); |
2130 | break; | | 2220 | break; |
2131 | case CI_MS_WINS1: | | 2221 | case CI_MS_WINS1: |
2132 | case CI_MS_WINS2: | | 2222 | case CI_MS_WINS2: |
2133 | p += 2; | | 2223 | p += 2; |
2134 | GETLONG(cilong, p); | | 2224 | GETLONG(cilong, p); |
2135 | printer(arg, "ms-wins %I", htonl(cilong)); | | 2225 | printer(arg, "ms-wins %I", htonl(cilong)); |
2136 | break; | | 2226 | break; |
2137 | } | | 2227 | } |
2138 | while (p < optend) { | | 2228 | while (p < optend) { |
2139 | GETCHAR(code, p); | | 2229 | GETCHAR(code, p); |
2140 | printer(arg, " %.2x", code); | | 2230 | printer(arg, " %.2x", code); |
2141 | } | | 2231 | } |