Sat Aug 7 20:38:13 2010 UTC ()
Apply changes from 2.4.5. Supposedly fixes some 3G issues.


(christos)
diff -r1.4 -r1.5 src/dist/pppd/pppd/ipcp.c

cvs diff -r1.4 -r1.5 src/dist/pppd/pppd/Attic/ipcp.c (expand / switch to unified diff)

--- src/dist/pppd/pppd/Attic/ipcp.c 2006/06/29 21:50:17 1.4
+++ src/dist/pppd/pppd/Attic/ipcp.c 2010/08/07 20:38:13 1.5
@@ -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
74static const char rcsid[] = RCSID; 75static const char rcsid[] = RCSID;
75#endif 76#endif
76 77
77/* global vars */ 78/* global vars */
78ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 79ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
79ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 80ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
80ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 81ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
81ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 82ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
82 83
83u_int32_t netmask = 0; /* IP netmask to set on interface */ 84u_int32_t netmask = 0; /* IP netmask to set on interface */
84 85
85bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ 86bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */
 87bool 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 */
88void (*ip_up_hook) __P((void)) = NULL; 90void (*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 */
91void (*ip_down_hook) __P((void)) = NULL; 93void (*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 */
94void (*ip_choose_hook) __P((u_int32_t *)) = NULL; 96void (*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 */
97struct notifier *ip_up_notifier = NULL; 99struct notifier *ip_up_notifier = NULL;
98struct notifier *ip_down_notifier = NULL; 100struct 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 */
243static void ipcp_init __P((int)); 252static void ipcp_init __P((int));
244static void ipcp_open __P((int)); 253static void ipcp_open __P((int));
@@ -568,26 +577,34 @@ parse_dotted_ip(p, vp) @@ -568,26 +577,34 @@ parse_dotted_ip(p, vp)
568static void 577static void
569ipcp_init(unit) 578ipcp_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 */
718static int 735static int
719ipcp_cilen(f) 736ipcp_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 */
759static void 779static void
760ipcp_addci(f, ucp, lenp) 780ipcp_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 */
849static int 886static 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
1314bad: 1397bad:
@@ -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 */
1649static int 1732static int
1650ip_demand_conf(u) 1733ip_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 */
1692static void 1776static void
1693ipcp_up(f) 1777ipcp_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 }