2 * ipcp.c - PPP IP Control Protocol.
4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5 * Use is subject to license terms.
7 * Copyright (c) 1989 Carnegie Mellon University.
10 * Redistribution and use in source and binary forms are permitted
11 * provided that the above copyright notice and this paragraph are
12 * duplicated in all such forms and that any documentation,
13 * advertising materials, and other materials related to such
14 * distribution and use acknowledge that the software was developed
15 * by Carnegie Mellon University. The name of the
16 * University may not be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * Copyright (c) 2016 by Delphix. All rights reserved.
26 #define RCSID "$Id: ipcp.c,v 1.54 2000/04/15 01:27:11 masputra Exp $"
35 #include <sys/param.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #if defined(_linux_) || defined(__linux__)
41 #include <netinet/in.h>
42 #include <netinet/tcp.h>
43 #include <arpa/inet.h>
48 #include "pathnames.h"
50 #if !defined(lint) && !defined(_lint)
51 static const char rcsid
[] = RCSID
;
55 ipcp_options ipcp_wantoptions
[NUM_PPP
]; /* Options that we want to request */
56 ipcp_options ipcp_gotoptions
[NUM_PPP
]; /* Options that peer ack'd */
57 ipcp_options ipcp_allowoptions
[NUM_PPP
]; /* Options we allow peer to request */
58 ipcp_options ipcp_hisoptions
[NUM_PPP
]; /* Options that we ack'd */
60 bool ipcp_from_hostname
= 0; /* Local IP address is from hostname lookup */
62 /* Hook for a plugin to know when IP protocol has come up */
63 void (*ip_up_hook
) __P((void)) = NULL
;
65 /* Hook for a plugin to know when IP protocol has come down */
66 void (*ip_down_hook
) __P((void)) = NULL
;
69 static bool default_route_set
[NUM_PPP
]; /* Have set up a default route */
70 static bool proxy_arp_set
[NUM_PPP
]; /* Have created proxy arp entry */
71 static bool ipcp_is_up
[NUM_PPP
]; /* have called np_up() */
72 static bool proxy_arp_quiet
[NUM_PPP
]; /* We should be quiet on error */
73 static bool disable_defaultip
= 0; /* Don't use hostname for IP addr */
76 * Callbacks for fsm code. (CI = Configuration Information)
78 static void ipcp_resetci
__P((fsm
*)); /* Reset our CI */
79 static int ipcp_cilen
__P((fsm
*)); /* Return length of our CI */
80 static void ipcp_addci
__P((fsm
*, u_char
*, int *)); /* Add our CI */
81 static int ipcp_ackci
__P((fsm
*, u_char
*, int)); /* Peer ack'd our CI */
82 static int ipcp_nakci
__P((fsm
*, u_char
*, int)); /* Peer nak'd our CI */
83 static int ipcp_rejci
__P((fsm
*, u_char
*, int)); /* Peer rej'd our CI */
84 static int ipcp_reqci
__P((fsm
*, u_char
*, int *, int)); /* Rcv CI */
85 static void ipcp_up
__P((fsm
*)); /* We're UP */
86 static void ipcp_down
__P((fsm
*)); /* We're DOWN */
87 static void ipcp_finished
__P((fsm
*)); /* Don't need lower layer */
88 static int setmsservaddr
__P((char *, u_int32_t
*));
90 fsm ipcp_fsm
[NUM_PPP
]; /* IPCP fsm structure */
92 static fsm_callbacks ipcp_callbacks
= { /* IPCP callback routines */
93 ipcp_resetci
, /* Reset our Configuration Information */
94 ipcp_cilen
, /* Length of our Configuration Information */
95 ipcp_addci
, /* Add our Configuration Information */
96 ipcp_ackci
, /* ACK our Configuration Information */
97 ipcp_nakci
, /* NAK our Configuration Information */
98 ipcp_rejci
, /* Reject our Configuration Information */
99 ipcp_reqci
, /* Request peer's Configuration Information */
100 ipcp_up
, /* Called when fsm reaches OPENED state */
101 ipcp_down
, /* Called when fsm leaves OPENED state */
102 NULL
, /* Called when we want the lower layer up */
103 ipcp_finished
, /* Called when we want the lower layer down */
104 NULL
, /* Retransmission is necessary */
105 NULL
, /* Called to handle protocol-specific codes */
106 "IPCP", /* String name of protocol */
107 NULL
/* Peer rejected a code number */
111 * Command-line options.
113 static int setvjslots
__P((char **));
114 static int setdnsaddr
__P((char **));
115 static int setwinsaddr
__P((char **));
116 static int autoproxyarp
__P((char **));
118 static option_t ipcp_option_list
[] = {
119 { "noip", o_bool
, &ipcp_protent
.enabled_flag
,
120 "Disable IP and IPCP" },
121 { "-ip", o_bool
, &ipcp_protent
.enabled_flag
,
122 "Disable IP and IPCP" },
123 { "novj", o_bool
, &ipcp_wantoptions
[0].neg_vj
,
124 "Disable VJ compression", OPT_A2COPY
, &ipcp_allowoptions
[0].neg_vj
},
125 { "-vj", o_bool
, &ipcp_wantoptions
[0].neg_vj
,
126 "Disable VJ compression", OPT_A2COPY
, &ipcp_allowoptions
[0].neg_vj
},
127 { "novjccomp", o_bool
, &ipcp_wantoptions
[0].cflag
,
128 "Disable VJ connection-ID compression", OPT_A2COPY
,
129 &ipcp_allowoptions
[0].cflag
},
130 { "-vjccomp", o_bool
, &ipcp_wantoptions
[0].cflag
,
131 "Disable VJ connection-ID compression", OPT_A2COPY
,
132 &ipcp_allowoptions
[0].cflag
},
133 { "vj-max-slots", o_special
, (void *)setvjslots
,
134 "Set maximum VJ header slots" },
135 { "ipcp-accept-local", o_bool
, &ipcp_wantoptions
[0].accept_local
,
136 "Accept peer's address for us", 1 },
137 { "ipcp-accept-remote", o_bool
, &ipcp_wantoptions
[0].accept_remote
,
138 "Accept peer's address for it", 1 },
139 { "ipparam", o_string
, &ipparam
,
140 "Set ip script parameter" },
141 { "noipdefault", o_bool
, &disable_defaultip
,
142 "Don't use name for default IP adrs", 1 },
143 { "ms-dns", o_special
, (void *)setdnsaddr
,
144 "DNS address for the peer's use" },
145 { "ms-wins", o_special
, (void *)setwinsaddr
,
146 "Nameserver for SMB over TCP/IP for peer" },
147 { "ipcp-restart", o_int
, &ipcp_fsm
[0].timeouttime
,
148 "Set timeout for IPCP" },
149 { "ipcp-max-terminate", o_int
, &ipcp_fsm
[0].maxtermtransmits
,
150 "Set max #xmits for term-reqs" },
151 { "ipcp-max-configure", o_int
, &ipcp_fsm
[0].maxconfreqtransmits
,
152 "Set max #xmits for conf-reqs" },
153 { "ipcp-max-failure", o_int
, &ipcp_fsm
[0].maxnakloops
,
154 "Set max #conf-naks for IPCP" },
155 { "defaultroute", o_bool
, &ipcp_wantoptions
[0].default_route
,
156 "Add default route", OPT_ENABLE
|1, &ipcp_allowoptions
[0].default_route
},
157 { "nodefaultroute", o_bool
, &ipcp_allowoptions
[0].default_route
,
158 "disable defaultroute option", OPT_A2COPY
,
159 &ipcp_wantoptions
[0].default_route
},
160 { "-defaultroute", o_bool
, &ipcp_allowoptions
[0].default_route
,
161 "disable defaultroute option", OPT_A2COPY
,
162 &ipcp_wantoptions
[0].default_route
},
163 { "proxyarp", o_bool
, &ipcp_wantoptions
[0].proxy_arp
,
164 "Add proxy ARP entry", OPT_ENABLE
|1, &ipcp_allowoptions
[0].proxy_arp
},
165 { "autoproxyarp", o_special_noarg
, (void *)autoproxyarp
,
166 "Add proxy ARP entry if needed", OPT_ENABLE
,
167 &ipcp_allowoptions
[0].proxy_arp
},
168 { "noproxyarp", o_bool
, &ipcp_allowoptions
[0].proxy_arp
,
169 "disable proxyarp option", OPT_A2COPY
, &ipcp_wantoptions
[0].proxy_arp
},
170 { "-proxyarp", o_bool
, &ipcp_allowoptions
[0].proxy_arp
,
171 "disable proxyarp option", OPT_A2COPY
, &ipcp_wantoptions
[0].proxy_arp
},
172 { "usepeerdns", o_bool
, &ipcp_wantoptions
[0].req_dns1
,
173 "Ask peer for DNS address(es)", OPT_A2COPY
|1,
174 &ipcp_wantoptions
[0].req_dns2
},
179 * Protocol entry points from main code.
181 static void ipcp_init
__P((int));
182 static void ipcp_open
__P((int));
183 static void ipcp_close
__P((int, char *));
184 static void ipcp_lowerup
__P((int));
185 static void ipcp_lowerdown
__P((int));
186 static void ipcp_input
__P((int, u_char
*, int));
187 static void ipcp_protrej
__P((int));
188 static int ipcp_printpkt
__P((u_char
*, int,
189 void (*) __P((void *, const char *, ...)), void *));
190 static void ip_check_options
__P((void));
191 static int ip_demand_conf
__P((int));
192 static int ip_active_pkt
__P((u_char
*, int));
193 static void ipcp_print_stat
__P((int, FILE *));
195 static void create_resolv
__P((u_int32_t
, u_int32_t
));
197 struct protent ipcp_protent
= {
218 static void ipcp_clear_addrs
__P((int, u_int32_t
, u_int32_t
));
219 static void ipcp_script
__P((char *)); /* Run an up/down script */
220 static void ipcp_script_done
__P((void *, int));
223 * Lengths of configuration options.
226 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
227 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
228 #define CILEN_ADDR 6 /* new-style single address option */
229 #define CILEN_ADDRS 10 /* old-style dual address option */
233 * This state variable is used to ensure that we don't
234 * run an ipcp-up/down script while one is already running.
236 static enum script_state
{
240 static pid_t ipcp_script_pid
;
243 * Make a string representation of a network IP address.
251 (void) slprintf(b
, sizeof(b
), "%I", ipaddr
);
260 * setvjslots - set maximum number of connection slots for VJ compression
268 if (!int_option(*argv
, &value
))
270 if (value
< 2 || value
> 16) {
271 option_error("vj-max-slots value must be between 2 and 16");
274 ipcp_wantoptions
[0].maxslotindex
=
275 ipcp_allowoptions
[0].maxslotindex
= value
- 1;
280 * setmsservaddr - Set the primary and secondary server addresses in the
281 * array. setdnsaddr() and setwinsaddr() call this function with either
282 * dnsaddr[] or winsaddr[] as the serverarray argument.
285 setmsservaddr(servname
, serverarray
)
287 u_int32_t
*serverarray
;
290 struct hostent
*hp
= NULL
;
292 addr
= inet_addr(servname
);
293 if (addr
== (u_int32_t
) -1) {
294 if ((hp
= gethostbyname(servname
)) == NULL
)
296 BCOPY(hp
->h_addr
, &addr
, sizeof (u_int32_t
));
300 * If there is no primary then this is the first instance of the
301 * option, we must set the primary. In that case, try to set the
302 * secondary to h_addr_list[1]. If the primary is already set, then
303 * this is the second instance of the option, and we must set
306 if (serverarray
[0] == 0) {
307 serverarray
[0] = addr
;
308 if (hp
!= NULL
&& hp
->h_addr_list
[1] != NULL
)
309 BCOPY(hp
->h_addr_list
[1], &serverarray
[1], sizeof (u_int32_t
));
311 serverarray
[1] = addr
;
313 serverarray
[1] = addr
;
320 * setdnsaddr - set the dns address(es)
326 if (setmsservaddr(*argv
, &(ipcp_allowoptions
[0].dnsaddr
[0])) == 0) {
327 option_error("invalid address parameter '%s' for ms-dns option", *argv
);
335 * setwinsaddr - set the wins address(es)
336 * This is primrarly used with the Samba package under UNIX or for pointing
337 * the caller to the existing WINS server on a Windows NT platform.
343 if (setmsservaddr(*argv
, &(ipcp_allowoptions
[0].winsaddr
[0])) == 0) {
344 option_error("invalid address parameter '%s' for ms-wins option",
353 * autoproxyarp -- enable proxy ARP but don't emit error messages if
354 * it's not actually needed.
361 ipcp_wantoptions
[0].proxy_arp
= 1;
362 proxy_arp_quiet
[0] = 1;
369 * ipcp_init - Initialize IPCP.
375 fsm
*f
= &ipcp_fsm
[unit
];
376 ipcp_options
*wo
= &ipcp_wantoptions
[unit
];
377 ipcp_options
*ao
= &ipcp_allowoptions
[unit
];
380 f
->protocol
= PPP_IPCP
;
381 f
->callbacks
= &ipcp_callbacks
;
382 fsm_init(&ipcp_fsm
[unit
]);
384 BZERO(wo
, sizeof(*wo
));
385 BZERO(ao
, sizeof(*ao
));
387 wo
->neg_addr
= wo
->old_addrs
= 1;
389 wo
->vj_protocol
= IPCP_VJ_COMP
;
390 wo
->maxslotindex
= MAX_STATES
- 1; /* really max index */
393 ao
->neg_addr
= ao
->old_addrs
= 1;
395 ao
->maxslotindex
= MAX_STATES
- 1;
399 * These aren't actually negotiated. Instead, they control
400 * whether the user may use the proxyarp and defaultroute options.
403 ao
->default_route
= 1;
404 proxy_arp_quiet
[unit
] = 0;
409 * ipcp_open - IPCP is allowed to come up.
415 fsm_open(&ipcp_fsm
[unit
]);
420 * ipcp_close - Take IPCP down.
423 ipcp_close(unit
, reason
)
427 fsm_close(&ipcp_fsm
[unit
], reason
);
432 * ipcp_lowerup - The lower layer is up.
438 fsm_lowerup(&ipcp_fsm
[unit
]);
443 * ipcp_lowerdown - The lower layer is down.
449 fsm_lowerdown(&ipcp_fsm
[unit
]);
454 * ipcp_input - Input IPCP packet.
457 ipcp_input(unit
, p
, len
)
462 fsm_input(&ipcp_fsm
[unit
], p
, len
);
467 * ipcp_protrej - A Protocol-Reject was received for IPCP.
473 fsm_protreject(&ipcp_fsm
[unit
]);
478 * ipcp_resetci - Reset our CI.
479 * Called by fsm_sconfreq, Send Configure Request.
485 ipcp_options
*wo
= &ipcp_wantoptions
[f
->unit
];
486 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
487 ipcp_options
*ao
= &ipcp_allowoptions
[f
->unit
];
489 wo
->req_addr
= (wo
->neg_addr
|| wo
->old_addrs
) &&
490 (ao
->neg_addr
|| ao
->old_addrs
);
491 if (wo
->ouraddr
== 0 || disable_defaultip
)
492 wo
->accept_local
= 1;
493 if (wo
->hisaddr
== 0)
494 wo
->accept_remote
= 1;
496 if (disable_defaultip
)
502 * ipcp_cilen - Return length of our CI.
503 * Called by fsm_sconfreq, Send Configure Request.
509 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
510 ipcp_options
*wo
= &ipcp_wantoptions
[f
->unit
];
511 ipcp_options
*ho
= &ipcp_hisoptions
[f
->unit
];
513 #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0)
514 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
515 #define LENCIADDR(neg) (neg ? (CILEN_ADDR) : 0)
518 * First see if we want to change our options to the old
519 * forms because we have received old forms from the peer.
521 if (go
->neg_addr
&& go
->old_addrs
&& !ho
->neg_addr
&& ho
->old_addrs
)
522 /* use the old style of address negotiation */
524 if (wo
->neg_vj
&& !go
->neg_vj
&& !go
->old_vj
) {
525 /* try an older style of VJ negotiation */
526 /* use the old style only if the peer did */
527 if (ho
->neg_vj
&& ho
->old_vj
) {
530 go
->vj_protocol
= ho
->vj_protocol
;
534 return (LENCIADDRS(!go
->neg_addr
&& go
->old_addrs
) +
535 LENCIVJ(go
->neg_vj
, go
->old_vj
) +
536 LENCIADDR(go
->neg_addr
) +
537 LENCIADDR(go
->req_dns1
) +
538 LENCIADDR(go
->req_dns2
)) ;
543 * ipcp_addci - Add our desired CIs to a packet.
544 * Called by fsm_sconfreq, Send Configure Request.
547 ipcp_addci(f
, ucp
, lenp
)
552 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
555 #define ADDCIADDRS(opt, neg, val1, val2) \
557 if (len >= CILEN_ADDRS) { \
559 PUTCHAR(CILEN_ADDRS, ucp); \
560 PUTNLONG(val1, ucp); \
561 PUTNLONG(val2, ucp); \
562 len -= CILEN_ADDRS; \
567 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
569 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
570 if (len >= vjlen) { \
572 PUTCHAR(vjlen, ucp); \
573 PUTSHORT(val, ucp); \
575 PUTCHAR(maxslotindex, ucp); \
576 PUTCHAR(cflag, ucp); \
583 #define ADDCIADDR(opt, neg, val) \
585 if (len >= CILEN_ADDR) { \
587 PUTCHAR(CILEN_ADDR, ucp); \
588 PUTNLONG(val, ucp); \
594 ADDCIADDRS(CI_ADDRS
, !go
->neg_addr
&& go
->old_addrs
, go
->ouraddr
,
597 ADDCIVJ(CI_COMPRESSTYPE
, go
->neg_vj
, go
->vj_protocol
, go
->old_vj
,
598 go
->maxslotindex
, go
->cflag
);
600 ADDCIADDR(CI_ADDR
, go
->neg_addr
, go
->ouraddr
);
602 ADDCIADDR(CI_MS_DNS1
, go
->req_dns1
, go
->dnsaddr
[0]);
604 ADDCIADDR(CI_MS_DNS2
, go
->req_dns2
, go
->dnsaddr
[1]);
611 * ipcp_ackci - Ack our CIs.
612 * Called by fsm_rconfack, Receive Configure ACK.
619 ipcp_ackci(f
, p
, len
)
624 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
625 u_short cilen
, citype
, cishort
;
627 u_char cimaxslotindex
, cicflag
;
630 * CIs must be in exactly the same order that we sent...
631 * Check packet length and CI length at each step.
632 * If we find any deviations, then this packet is bad.
635 #define ACKCHECK(opt, olen) \
636 if ((len -= olen) < 0) \
638 GETCHAR(citype, p); \
640 if (cilen != olen || \
644 #define ACKCIADDRS(opt, neg, val1, val2) \
646 ACKCHECK(opt, CILEN_ADDRS) \
647 GETNLONG(cilong, p); \
648 if (val1 != cilong) \
650 GETNLONG(cilong, p); \
651 if (val2 != cilong) \
655 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
657 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
658 ACKCHECK(opt, vjlen) \
659 GETSHORT(cishort, p); \
660 if (cishort != val) \
663 GETCHAR(cimaxslotindex, p); \
664 if (cimaxslotindex != maxslotindex) \
666 GETCHAR(cicflag, p); \
667 if (cicflag != cflag) \
672 #define ACKCIADDR(opt, neg, val) \
674 ACKCHECK(opt, CILEN_ADDR) \
675 GETNLONG(cilong, p); \
680 ACKCIADDRS(CI_ADDRS
, !go
->neg_addr
&& go
->old_addrs
, go
->ouraddr
,
683 ACKCIVJ(CI_COMPRESSTYPE
, go
->neg_vj
, go
->vj_protocol
, go
->old_vj
,
684 go
->maxslotindex
, go
->cflag
);
686 ACKCIADDR(CI_ADDR
, go
->neg_addr
, go
->ouraddr
);
688 ACKCIADDR(CI_MS_DNS1
, go
->req_dns1
, go
->dnsaddr
[0]);
690 ACKCIADDR(CI_MS_DNS2
, go
->req_dns2
, go
->dnsaddr
[1]);
693 * If there are any remaining CIs, then this packet is bad.
700 IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
705 * ipcp_nakci - Peer has sent a NAK for some of our CIs.
706 * This should not modify any state if the Nak is bad
707 * or if IPCP is in the OPENED state.
708 * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
715 ipcp_nakci(f
, p
, len
)
720 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
721 u_char cimaxslotindex
, cicflag
;
722 u_char citype
, cilen
, *next
;
724 u_int32_t ciaddr1
, ciaddr2
;
725 ipcp_options no
; /* options we've seen Naks for */
726 ipcp_options
try; /* options to request next time */
728 BZERO(&no
, sizeof(no
));
732 * Any Nak'd CIs must be in exactly the same order that we sent.
733 * Check packet length and CI length at each step.
734 * If we find any deviations, then this packet is bad.
736 #define NAKCIADDRS(opt, neg, code) \
738 (cilen = p[1]) == CILEN_ADDRS && \
743 GETNLONG(ciaddr1, p); \
744 GETNLONG(ciaddr2, p); \
749 #define NAKCIVJ(opt, neg, code) \
751 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
756 GETSHORT(cishort, p); \
761 #define NAKCIADDR(opt, neg, code) \
763 (cilen = p[1]) == CILEN_ADDR && \
768 GETNLONG(ciaddr1, p); \
774 * Accept the peer's idea of {our,its} address, if different
775 * from our idea, only if the accept_{local,remote} flag is set.
777 NAKCIADDRS(CI_ADDRS
, !go
->neg_addr
&& go
->old_addrs
,
778 if (go
->accept_local
&& ciaddr1
) { /* Do we know our address? */
779 try.ouraddr
= ciaddr1
;
781 if (go
->accept_remote
&& ciaddr2
) { /* Does it know its? */
782 try.hisaddr
= ciaddr2
;
787 * Accept the peer's value of maxslotindex provided that it
788 * is less than what we asked for. Turn off slot-ID compression
789 * if the peer wants. Send old-style compress-type option if
792 NAKCIVJ(CI_COMPRESSTYPE
, neg_vj
,
793 if (cilen
== CILEN_VJ
) {
794 GETCHAR(cimaxslotindex
, p
);
796 if (cishort
== IPCP_VJ_COMP
) {
798 if (cimaxslotindex
< go
->maxslotindex
)
799 try.maxslotindex
= cimaxslotindex
;
806 if (cishort
== IPCP_VJ_COMP
|| cishort
== IPCP_VJ_COMP_OLD
) {
808 try.vj_protocol
= cishort
;
815 NAKCIADDR(CI_ADDR
, neg_addr
,
816 if (go
->accept_local
&& ciaddr1
) { /* Do we know our address? */
817 try.ouraddr
= ciaddr1
;
821 NAKCIADDR(CI_MS_DNS1
, req_dns1
,
822 try.dnsaddr
[0] = ciaddr1
;
825 NAKCIADDR(CI_MS_DNS2
, req_dns2
,
826 try.dnsaddr
[1] = ciaddr1
;
830 * There may be remaining CIs, if the peer is requesting negotiation
831 * on an option that we didn't include in our request packet.
832 * If they want to negotiate about IP addresses, we comply.
833 * If they want us to ask for compression, we refuse.
835 while (len
> CILEN_VOID
) {
838 if( (len
-= cilen
) < 0 )
840 next
= p
+ cilen
- 2;
843 case CI_COMPRESSTYPE
:
844 if (go
->neg_vj
|| no
.neg_vj
||
845 (cilen
!= CILEN_VJ
&& cilen
!= CILEN_COMPRESS
))
850 if ((!go
->neg_addr
&& go
->old_addrs
) || no
.old_addrs
851 || cilen
!= CILEN_ADDRS
)
855 GETNLONG(ciaddr1
, p
);
856 if (ciaddr1
&& go
->accept_local
)
857 try.ouraddr
= ciaddr1
;
858 GETNLONG(ciaddr2
, p
);
859 if (ciaddr2
&& go
->accept_remote
)
860 try.hisaddr
= ciaddr2
;
864 if (go
->neg_addr
|| no
.neg_addr
|| cilen
!= CILEN_ADDR
)
867 GETNLONG(ciaddr1
, p
);
868 if (ciaddr1
&& go
->accept_local
)
869 try.ouraddr
= ciaddr1
;
870 if (try.ouraddr
!= 0)
879 * OK, the Nak is good. Now we can update state.
880 * If there are any remaining options, we ignore them.
882 if (f
->state
!= OPENED
)
888 IPCPDEBUG(("ipcp_nakci: received bad Nak!"));
894 * ipcp_rejci - Reject some of our CIs.
895 * Callback from fsm_rconfnakrej.
898 ipcp_rejci(f
, p
, len
)
903 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
904 u_char cimaxslotindex
, ciflag
, cilen
;
907 ipcp_options
try; /* options to request next time */
911 * Any Rejected CIs must be in exactly the same order that we sent.
912 * Check packet length and CI length at each step.
913 * If we find any deviations, then this packet is bad.
915 #define REJCIADDRS(opt, neg, val1, val2) \
917 (cilen = p[1]) == CILEN_ADDRS && \
922 GETNLONG(cilong, p); \
923 /* Check rejected value. */ \
924 if (cilong != val1) \
926 GETNLONG(cilong, p); \
927 /* Check rejected value. */ \
928 if (cilong != val2) \
933 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
935 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
940 GETSHORT(cishort, p); \
941 /* Check rejected value. */ \
942 if (cishort != val) \
945 GETCHAR(cimaxslotindex, p); \
946 if (cimaxslotindex != maxslot) \
948 GETCHAR(ciflag, p); \
949 if (ciflag != cflag) \
955 #define REJCIADDR(opt, neg, addr) \
957 ((cilen = p[1]) == CILEN_ADDR) && \
962 GETNLONG(cilong, p); \
963 /* Check rejected value. */ \
964 if (cilong != addr) \
969 REJCIADDRS(CI_ADDRS
, !go
->neg_addr
&& go
->old_addrs
,
970 go
->ouraddr
, go
->hisaddr
);
972 REJCIVJ(CI_COMPRESSTYPE
, neg_vj
, go
->vj_protocol
, go
->old_vj
,
973 go
->maxslotindex
, go
->cflag
);
975 REJCIADDR(CI_ADDR
, neg_addr
, go
->ouraddr
);
977 REJCIADDR(CI_MS_DNS1
, req_dns1
, go
->dnsaddr
[0]);
979 REJCIADDR(CI_MS_DNS2
, req_dns2
, go
->dnsaddr
[1]);
982 * If there are any remaining CIs, then this packet is bad.
987 * Now we can update state.
989 if (f
->state
!= OPENED
)
994 IPCPDEBUG(("ipcp_rejci: received bad Reject!"));
1000 * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
1001 * Callback from fsm_rconfreq, Receive Configure Request
1003 * Returns: CODE_CONFACK, CODE_CONFNAK or CODE_CONFREJ and input
1004 * packet modified appropriately. If reject_if_disagree is non-zero,
1005 * doesn't return CODE_CONFNAK; returns CODE_CONFREJ if it can't
1006 * return CODE_CONFACK.
1009 ipcp_reqci(f
, p
, lenp
, dont_nak
)
1011 u_char
*p
; /* Requested CIs */
1012 int *lenp
; /* Length of requested CIs */
1015 ipcp_options
*wo
= &ipcp_wantoptions
[f
->unit
];
1016 ipcp_options
*ho
= &ipcp_hisoptions
[f
->unit
];
1017 ipcp_options
*ao
= &ipcp_allowoptions
[f
->unit
];
1018 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
1020 u_char
*p0
, *nakp
, *rejp
, *prev
;
1022 int len
, cilen
, type
;
1023 u_int32_t tl
, ciaddr1
, ciaddr2
; /* Parsed address values */
1024 u_char maxslotindex
, cflag
;
1032 * Reset all its options.
1034 BZERO(ho
, sizeof(*ho
));
1037 * Process all its options.
1039 for (len
= *lenp
; len
> 0; len
-= cilen
, p
= prev
+ cilen
) {
1040 if ((len
< 2) || p
[1] > len
) {
1042 * RFC 1661 page 40 -- if the option extends beyond the
1043 * packet, then discard the entire packet.
1048 newret
= CODE_CONFACK
;
1053 switch (type
) { /* Check CI type */
1055 if (!ao
->old_addrs
|| ho
->neg_addr
) {
1056 newret
= CODE_CONFREJ
;
1060 if (cilen
!= CILEN_ADDRS
) {
1062 * rfc1661, page 40 -- a recongnized option with an
1063 * invalid length should be Nak'ed.
1065 newret
= CODE_CONFNAK
;
1066 ciaddr1
= wo
->hisaddr
;
1067 ciaddr2
= wo
->ouraddr
;
1071 * If it has no address, or if we both have its
1072 * address but disagree about it, then NAK it with our
1073 * idea. In particular, if we don't know its address,
1074 * but it does, then accept it.
1076 GETNLONG(ciaddr1
, p
);
1077 if (ciaddr1
!= wo
->hisaddr
&&
1078 (ciaddr1
== 0 || !wo
->accept_remote
)) {
1079 newret
= CODE_CONFNAK
;
1080 ciaddr1
= wo
->hisaddr
;
1081 } else if (ciaddr1
== 0 && wo
->hisaddr
== 0) {
1083 * If neither we nor he knows his address, reject
1086 newret
= CODE_CONFREJ
;
1087 wo
->req_addr
= 0; /* don't NAK with 0.0.0.0 later */
1089 } else if (ciaddr1
!= 0) {
1090 go
->hisaddr
= ciaddr1
;
1094 * If he doesn't know our address, or if we both have
1095 * our address * but disagree about it, then NAK it
1098 GETNLONG(ciaddr2
, p
);
1099 if (ciaddr2
!= wo
->ouraddr
) {
1100 if (ciaddr2
== 0 || !wo
->accept_local
) {
1101 newret
= CODE_CONFNAK
;
1102 ciaddr2
= wo
->ouraddr
;
1104 go
->ouraddr
= ciaddr2
; /* accept peer's idea */
1109 if (newret
== CODE_CONFNAK
) {
1110 PUTCHAR(type
, nakp
);
1111 PUTCHAR(CILEN_ADDRS
, nakp
);
1112 PUTNLONG(ciaddr1
, nakp
);
1113 PUTNLONG(ciaddr2
, nakp
);
1117 ho
->hisaddr
= ciaddr1
;
1118 ho
->ouraddr
= ciaddr2
;
1122 if (!ao
->neg_addr
|| ho
->old_addrs
) {
1123 newret
= CODE_CONFREJ
;
1127 if (cilen
!= CILEN_ADDR
) {
1129 * rfc1661, page 40 -- a recongnized option with an
1130 * invalid length should be Nak'ed.
1132 newret
= CODE_CONFNAK
;
1133 ciaddr1
= wo
->hisaddr
;
1137 * If he has no address, or if we both have his
1138 * address but disagree about it, then NAK it with our
1139 * idea. In particular, if we don't know his address,
1140 * but he does, then accept it.
1142 GETNLONG(ciaddr1
, p
);
1143 if (ciaddr1
!= wo
->hisaddr
&&
1144 (ciaddr1
== 0 || !wo
->accept_remote
)) {
1145 newret
= CODE_CONFNAK
;
1146 ciaddr1
= wo
->hisaddr
;
1147 } else if (ciaddr1
== 0 && wo
->hisaddr
== 0 &&
1148 wo
->default_route
!= 0) {
1149 newret
= CODE_CONFNAK
;
1151 * If this is a dialup line (default_route is
1152 * set), and neither side knows about its address,
1153 * suggest an arbitrary rfc1918 address.
1155 ciaddr1
= htonl(0xc0a80101 + ifunit
);
1156 dbglog("Peer address unknown; suggesting %I", ciaddr1
);
1157 } else if (ciaddr1
== 0 && wo
->hisaddr
== 0) {
1159 * If this is not a dialup line, don't ACK an
1160 * address of 0.0.0.0 - reject it instead.
1162 newret
= CODE_CONFREJ
;
1163 wo
->req_addr
= 0; /* don't NAK with 0.0.0.0 later */
1168 if (newret
== CODE_CONFNAK
) {
1169 PUTCHAR(type
, nakp
);
1170 PUTCHAR(CILEN_ADDR
, nakp
);
1171 PUTNLONG(ciaddr1
, nakp
);
1175 ho
->hisaddr
= ciaddr1
;
1180 /* Warning -- these options work backwards. */
1181 /* Microsoft primary or secondary DNS request */
1182 d
= (type
== CI_MS_DNS2
? 1 : 0);
1184 if (ao
->dnsaddr
[d
] == 0) {
1185 newret
= CODE_CONFREJ
;
1189 if (cilen
!= CILEN_ADDR
) {
1190 newret
= CODE_CONFNAK
;
1193 if (tl
!= ao
->dnsaddr
[d
]) {
1194 newret
= CODE_CONFNAK
;
1198 if (newret
== CODE_CONFNAK
) {
1199 PUTCHAR(type
, nakp
);
1200 PUTCHAR(CILEN_ADDR
, nakp
);
1201 PUTNLONG(ao
->dnsaddr
[d
], nakp
);
1207 /* Warning -- these options work backwards. */
1208 /* Microsoft primary or secondary WINS request */
1209 d
= (type
== CI_MS_WINS2
? 1 : 0);
1211 if (ao
->winsaddr
[d
] == 0) {
1212 newret
= CODE_CONFREJ
;
1216 if (cilen
!= CILEN_ADDR
) {
1217 newret
= CODE_CONFNAK
;
1220 if (tl
!= ao
->winsaddr
[d
]) {
1221 newret
= CODE_CONFNAK
;
1225 if (newret
== CODE_CONFNAK
) {
1226 PUTCHAR(type
, nakp
);
1227 PUTCHAR(CILEN_ADDR
, nakp
);
1228 PUTNLONG(ao
->winsaddr
[d
], nakp
);
1232 case CI_COMPRESSTYPE
:
1234 newret
= CODE_CONFREJ
;
1238 maxslotindex
= ao
->maxslotindex
;
1240 if (cilen
!= CILEN_VJ
&& cilen
!= CILEN_COMPRESS
) {
1241 newret
= CODE_CONFNAK
;
1242 cishort
= IPCP_VJ_COMP
;
1244 GETSHORT(cishort
, p
);
1245 if (cishort
!= IPCP_VJ_COMP
&&
1246 (cishort
!= IPCP_VJ_COMP_OLD
|| cilen
!= CILEN_COMPRESS
)) {
1247 newret
= CODE_CONFNAK
;
1248 cishort
= IPCP_VJ_COMP
;
1249 } else if (cilen
== CILEN_VJ
) {
1250 GETCHAR(maxslotindex
, p
);
1251 if (maxslotindex
> ao
->maxslotindex
) {
1252 newret
= CODE_CONFNAK
;
1253 maxslotindex
= ao
->maxslotindex
;
1256 if (cflag
!= 0 && ao
->cflag
== 0) {
1257 newret
= CODE_CONFNAK
;
1262 maxslotindex
= MAX_STATES
- 1;
1267 if (newret
== CODE_CONFNAK
) {
1268 PUTCHAR(type
, nakp
);
1269 if (cishort
== IPCP_VJ_COMP
) {
1270 PUTCHAR(CILEN_VJ
, nakp
);
1271 PUTSHORT(cishort
, nakp
);
1272 PUTCHAR(maxslotindex
, nakp
);
1273 PUTCHAR(cflag
, nakp
);
1275 PUTCHAR(CILEN_COMPRESS
, nakp
);
1276 PUTSHORT(cishort
, nakp
);
1280 ho
->vj_protocol
= cishort
;
1281 ho
->maxslotindex
= maxslotindex
;
1286 newret
= CODE_CONFREJ
;
1290 /* Cope with confused peers. */
1295 * If this is an Ack'able CI, but we're sending back a Nak,
1296 * don't include this CI.
1298 if (newret
== CODE_CONFACK
&& ret
!= CODE_CONFACK
)
1301 if (newret
== CODE_CONFNAK
) {
1303 newret
= CODE_CONFREJ
;
1305 /* Ignore subsequent Nak'able things if rejecting. */
1306 if (ret
== CODE_CONFREJ
)
1312 if (newret
== CODE_CONFREJ
) {
1315 BCOPY(prev
, rejp
, cilen
);
1321 * If we aren't rejecting this packet, and we want to negotiate
1322 * their address, and they didn't send their address, then we
1323 * send a NAK with a CI_ADDR option appended. We assume the
1324 * input buffer is long enough that we can append the extra
1327 if (ret
!= CODE_CONFREJ
&& !ho
->neg_addr
&& !ho
->old_addrs
&&
1328 wo
->req_addr
&& !dont_nak
) {
1329 if (ret
== CODE_CONFACK
)
1330 wo
->req_addr
= 0; /* don't ask again */
1332 PUTCHAR(CI_ADDR
, nakp
);
1333 PUTCHAR(CILEN_ADDR
, nakp
);
1334 PUTNLONG(wo
->hisaddr
, nakp
);
1340 sys_block_proto(PPP_IP
);
1343 *lenp
= nakp
- nak_buffer
;
1344 BCOPY(nak_buffer
, p0
, *lenp
);
1351 return (ret
); /* Return final code */
1356 * ip_check_options - check that any IP-related options are OK,
1357 * and assign appropriate defaults.
1364 ipcp_options
*wo
= &ipcp_wantoptions
[0];
1367 * Default our local IP address based on our hostname.
1368 * If local IP address already given, don't bother.
1370 if (wo
->ouraddr
== 0) {
1372 * Look up our hostname (possibly with domain name appended)
1373 * and take the first IP address as our local IP address.
1374 * If there isn't an IP address for our hostname, too bad.
1376 wo
->accept_local
= 1; /* don't insist on this default value */
1377 if ((hp
= gethostbyname(hostname
)) != NULL
) {
1378 BCOPY(hp
->h_addr
, &local
, sizeof (hp
->h_addr
));
1379 if (local
!= 0 && !bad_ip_adrs(local
)) {
1380 wo
->ouraddr
= local
;
1381 ipcp_from_hostname
= 1;
1389 * ip_demand_conf - configure the interface as though
1390 * IPCP were up, for use with dial-on-demand.
1396 ipcp_options
*wo
= &ipcp_wantoptions
[u
];
1398 if (wo
->hisaddr
== 0) {
1399 /* make up an arbitrary address for the peer */
1400 wo
->hisaddr
= htonl(0x0a707070 + ifunit
);
1401 wo
->accept_remote
= 1;
1403 if (wo
->ouraddr
== 0) {
1404 /* make up an arbitrary address for us */
1405 wo
->ouraddr
= htonl(0x0a404040 + ifunit
);
1406 wo
->accept_local
= 1;
1407 disable_defaultip
= 1; /* don't tell the peer this address */
1409 if (!sifaddr(u
, wo
->ouraddr
, wo
->hisaddr
, GetMask(wo
->ouraddr
)))
1413 if (!sifnpmode(u
, PPP_IP
, NPMODE_QUEUE
))
1415 if (wo
->default_route
&& sifdefaultroute(u
, wo
->ouraddr
, wo
->hisaddr
))
1416 default_route_set
[u
] = 1;
1417 if (wo
->proxy_arp
&& sifproxyarp(u
, wo
->hisaddr
, proxy_arp_quiet
[u
]))
1418 proxy_arp_set
[u
] = 1;
1420 notice("local IP address %I", wo
->ouraddr
);
1421 notice("remote IP address %I", wo
->hisaddr
);
1428 * ipcp_up - IPCP has come UP.
1430 * Configure the IP network interface appropriately and bring it up.
1437 ipcp_options
*ho
= &ipcp_hisoptions
[f
->unit
];
1438 ipcp_options
*go
= &ipcp_gotoptions
[f
->unit
];
1439 ipcp_options
*wo
= &ipcp_wantoptions
[f
->unit
];
1441 IPCPDEBUG(("ipcp: up"));
1444 * We must have a non-zero IP address for both ends of the link.
1446 if (ho
->hisaddr
== 0)
1447 ho
->hisaddr
= wo
->hisaddr
;
1449 if (ho
->hisaddr
== 0) {
1450 if (wo
->accept_remote
) {
1451 /* Pick some rfc1918 address. */
1452 ho
->hisaddr
= htonl(0xc0a80101 + ifunit
);
1453 dbglog("Peer refused to provide his address; assuming %I",
1456 error("Could not determine remote IP address");
1457 ipcp_close(f
->unit
, "Could not determine remote IP address");
1461 if (go
->ouraddr
== 0) {
1462 error("Could not determine local IP address");
1463 ipcp_close(f
->unit
, "Could not determine local IP address");
1466 script_setenv("IPLOCAL", ip_ntoa(go
->ouraddr
), 0);
1467 script_setenv("IPREMOTE", ip_ntoa(ho
->hisaddr
), 1);
1470 * Check that the peer is allowed to use the IP address it wants.
1472 if (!auth_ip_addr(f
->unit
, ho
->hisaddr
)) {
1473 error("Peer is not authorized to use remote address %I", ho
->hisaddr
);
1474 ipcp_close(f
->unit
, "Unauthorized remote IP address");
1478 if ((go
->req_dns1
&& go
->dnsaddr
[0] != 0) ||
1479 (go
->req_dns2
&& go
->dnsaddr
[1] != 0)) {
1480 script_setenv("USEPEERDNS", "1", 0);
1481 if (go
->dnsaddr
[0] != 0)
1482 script_setenv("DNS1", ip_ntoa(go
->dnsaddr
[0]), 0);
1483 if (go
->dnsaddr
[1] != 0)
1484 script_setenv("DNS2", ip_ntoa(go
->dnsaddr
[1]), 0);
1485 create_resolv(go
->dnsaddr
[0], go
->dnsaddr
[1]);
1488 /* set tcp compression */
1489 if (sifvjcomp(f
->unit
, ho
->neg_vj
, ho
->cflag
, ho
->maxslotindex
) != 1) {
1490 ipcp_close(f
->unit
, "Could not enable VJ TCP header compression");
1495 * If we are doing dial-on-demand, the interface is already
1496 * configured, so we put out any saved-up packets, then set the
1497 * interface to pass IP packets.
1500 if (go
->ouraddr
!= wo
->ouraddr
|| ho
->hisaddr
!= wo
->hisaddr
) {
1501 ipcp_clear_addrs(f
->unit
, wo
->ouraddr
, wo
->hisaddr
);
1502 if (go
->ouraddr
!= wo
->ouraddr
) {
1503 warn("Local IP address changed to %I", go
->ouraddr
);
1504 script_setenv("OLDIPLOCAL", ip_ntoa(wo
->ouraddr
), 0);
1505 wo
->ouraddr
= go
->ouraddr
;
1507 script_unsetenv("OLDIPLOCAL");
1508 if (ho
->hisaddr
!= wo
->hisaddr
) {
1509 warn("Remote IP address changed to %I", ho
->hisaddr
);
1510 script_setenv("OLDIPREMOTE", ip_ntoa(wo
->hisaddr
), 0);
1511 wo
->hisaddr
= ho
->hisaddr
;
1513 script_unsetenv("OLDIPREMOTE");
1515 /* Set the interface to the new addresses */
1516 mask
= GetMask(go
->ouraddr
);
1517 if (!sifaddr(f
->unit
, go
->ouraddr
, ho
->hisaddr
, mask
)) {
1518 warn("Interface configuration failed");
1519 ipcp_close(f
->unit
, "Interface configuration failed");
1523 /* assign a default route through the interface if required */
1524 if (wo
->default_route
)
1525 if (sifdefaultroute(f
->unit
, go
->ouraddr
, ho
->hisaddr
))
1526 default_route_set
[f
->unit
] = 1;
1528 /* Make a proxy ARP entry if requested. */
1529 if (wo
->proxy_arp
&&
1530 sifproxyarp(f
->unit
, ho
->hisaddr
, proxy_arp_quiet
[f
->unit
]))
1531 proxy_arp_set
[f
->unit
] = 1;
1534 demand_rexmit(PPP_IP
);
1535 if (sifnpmode(f
->unit
, PPP_IP
, NPMODE_PASS
) != 1) {
1536 ipcp_close(f
->unit
, "Interface configuration failed.");
1542 * Set IP addresses and (if specified) netmask.
1544 mask
= GetMask(go
->ouraddr
);
1547 /* bring the interface up for IP */
1548 if (!sifup(f
->unit
)) {
1549 warn("Interface failed to come up");
1550 ipcp_close(f
->unit
, "Interface configuration failed");
1555 if (!sifaddr(f
->unit
, go
->ouraddr
, ho
->hisaddr
, mask
)) {
1556 warn("Interface configuration failed");
1557 ipcp_close(f
->unit
, "Interface configuration failed");
1562 /* bring the interface up for IP */
1563 if (!sifup(f
->unit
)) {
1564 warn("Interface failed to come up");
1565 ipcp_close(f
->unit
, "Interface configuration failed");
1570 if (sifnpmode(f
->unit
, PPP_IP
, NPMODE_PASS
) != 1) {
1571 ipcp_close(f
->unit
, "Interface configuration failed.");
1575 /* assign a default route through the interface if required */
1576 if (wo
->default_route
)
1577 if (sifdefaultroute(f
->unit
, go
->ouraddr
, ho
->hisaddr
))
1578 default_route_set
[f
->unit
] = 1;
1580 /* Make a proxy ARP entry if requested. */
1581 if (wo
->proxy_arp
&&
1582 sifproxyarp(f
->unit
, ho
->hisaddr
, proxy_arp_quiet
[f
->unit
]))
1583 proxy_arp_set
[f
->unit
] = 1;
1585 wo
->ouraddr
= go
->ouraddr
;
1587 notice("local IP address %I", go
->ouraddr
);
1588 notice("remote IP address %I", ho
->hisaddr
);
1589 if (go
->dnsaddr
[0] != 0)
1590 notice("primary DNS address %I", go
->dnsaddr
[0]);
1591 if (go
->dnsaddr
[1] != 0)
1592 notice("secondary DNS address %I", go
->dnsaddr
[1]);
1595 np_up(f
->unit
, PPP_IP
);
1596 ipcp_is_up
[f
->unit
] = 1;
1598 if (ip_up_hook
!= NULL
)
1602 * Execute the ip-up script, like this:
1603 * /etc/ppp/ip-up interface tty speed local-IP remote-IP
1605 if (ipcp_script_state
== s_down
&& ipcp_script_pid
== 0) {
1606 ipcp_script_state
= s_up
;
1607 ipcp_script(_PATH_IPUP
);
1609 sys_unblock_proto(PPP_IP
);
1614 * ipcp_down - IPCP has gone DOWN.
1616 * Take the IP network interface down, clear its addresses
1617 * and delete routes through it.
1623 IPCPDEBUG(("ipcp: down"));
1624 /* XXX a bit IPv4-centric here, we only need to get the stats
1625 * before the interface is marked down. */
1626 update_link_stats(f
->unit
);
1627 if (ip_down_hook
!= NULL
)
1629 if (ipcp_is_up
[f
->unit
]) {
1630 ipcp_is_up
[f
->unit
] = 0;
1631 np_down(f
->unit
, PPP_IP
);
1633 if (sifvjcomp(f
->unit
, 0, 0, 0) != 1) {
1635 warn("Failed to disable VJ TCP header compression.");
1639 * If we are doing dial-on-demand, set the interface
1640 * to queue up outgoing packets (for now).
1643 if (sifnpmode(f
->unit
, PPP_IP
, NPMODE_QUEUE
) != 1) {
1645 warn("Failed to enable Queueing on outgoing packets.");
1648 if (sifnpmode(f
->unit
, PPP_IP
, NPMODE_ERROR
) != 1) {
1650 warn("Could not set interface to drop packets.");
1652 if (sifdown(f
->unit
) != 1)
1653 warn("Could not bring interface down.");
1654 ipcp_clear_addrs(f
->unit
, ipcp_gotoptions
[f
->unit
].ouraddr
,
1655 ipcp_hisoptions
[f
->unit
].hisaddr
);
1658 /* Execute the ip-down script */
1659 if (ipcp_script_state
== s_up
&& ipcp_script_pid
== 0) {
1660 ipcp_script_state
= s_down
;
1661 ipcp_script(_PATH_IPDOWN
);
1667 * ipcp_clear_addrs() - clear the interface addresses, routes,
1668 * proxy arp entries, etc.
1671 ipcp_clear_addrs(unit
, ouraddr
, hisaddr
)
1673 u_int32_t ouraddr
; /* local address */
1674 u_int32_t hisaddr
; /* remote address */
1676 if (proxy_arp_set
[unit
]) {
1677 (void) cifproxyarp(unit
, hisaddr
);
1678 proxy_arp_set
[unit
] = 0;
1680 if (default_route_set
[unit
]) {
1681 (void) cifdefaultroute(unit
, ouraddr
, hisaddr
);
1682 default_route_set
[unit
] = 0;
1684 if (cifaddr(unit
, ouraddr
, hisaddr
) != 1)
1685 warn("Could not clear addresses");
1690 * ipcp_finished - possibly shut down the lower layers.
1696 np_finished(f
->unit
, PPP_IP
);
1701 * ipcp_script_done - called when the ip-up or ip-down script
1706 ipcp_script_done(arg
, status
)
1710 ipcp_script_pid
= 0;
1711 switch (ipcp_script_state
) {
1713 if (ipcp_fsm
[0].state
!= OPENED
) {
1714 ipcp_script_state
= s_down
;
1715 ipcp_script(_PATH_IPDOWN
);
1719 if (ipcp_fsm
[0].state
== OPENED
) {
1720 ipcp_script_state
= s_up
;
1721 ipcp_script(_PATH_IPUP
);
1729 * ipcp_script - Execute a script with arguments
1730 * interface-name tty-name speed local-IP remote-IP.
1736 char strspeed
[32], strlocal
[32], strremote
[32];
1739 (void) slprintf(strspeed
, sizeof(strspeed
), "%d", baud_rate
);
1740 (void) slprintf(strlocal
, sizeof(strlocal
), "%I",
1741 ipcp_gotoptions
[0].ouraddr
);
1742 (void) slprintf(strremote
, sizeof(strremote
), "%I",
1743 ipcp_hisoptions
[0].hisaddr
);
1750 argv
[5] = strremote
;
1753 ipcp_script_pid
= run_program(script
, argv
, 0, ipcp_script_done
, NULL
);
1757 * create_resolv - create the replacement resolv.conf file
1760 create_resolv(peerdns1
, peerdns2
)
1761 u_int32_t peerdns1
, peerdns2
;
1765 f
= fopen(_PATH_RESOLV
, "w");
1767 error("Failed to create %s: %m", _PATH_RESOLV
);
1772 if (fprintf(f
, "nameserver %s\n", ip_ntoa(peerdns1
)) <= 0)
1773 error("Write failed to %s: %m", _PATH_RESOLV
);
1776 if (fprintf(f
, "nameserver %s\n", ip_ntoa(peerdns2
)) <= 0)
1777 error("Write failed to %s: %m", _PATH_RESOLV
);
1780 error("Failed to close %s: %m", _PATH_RESOLV
);
1784 * ipcp_printpkt - print the contents of an IPCP packet.
1787 ipcp_printpkt(p
, plen
, printer
, arg
)
1790 void (*printer
) __P((void *, const char *, ...));
1793 int code
, id
, len
, olen
;
1794 u_char
*pstart
, *optend
;
1798 if (plen
< HEADERLEN
)
1804 if (len
< HEADERLEN
|| len
> plen
)
1807 printer(arg
, " %s id=0x%x", code_name(code
, 1), id
);
1814 /* print option list */
1819 if (olen
< 2 || olen
> len
) {
1827 if (olen
== CILEN_ADDRS
) {
1829 GETNLONG(cilong
, p
);
1830 printer(arg
, "addrs %I", cilong
);
1831 GETNLONG(cilong
, p
);
1832 printer(arg
, " %I", cilong
);
1835 case CI_COMPRESSTYPE
:
1836 if (olen
>= CILEN_COMPRESS
) {
1838 GETSHORT(cishort
, p
);
1839 printer(arg
, "compress ");
1844 case IPCP_VJ_COMP_OLD
:
1845 printer(arg
, "old-VJ");
1848 printer(arg
, "0x%x", cishort
);
1853 if (olen
== CILEN_ADDR
) {
1855 GETNLONG(cilong
, p
);
1856 printer(arg
, "addr %I", cilong
);
1862 GETNLONG(cilong
, p
);
1863 printer(arg
, "ms-dns%d %I", (code
== CI_MS_DNS1
? 1 : 2),
1869 GETNLONG(cilong
, p
);
1870 printer(arg
, "ms-wins%d %I", (code
== CI_MS_WINS1
? 1 : 2),
1875 GETNLONG(cilong
, p
);
1876 printer(arg
, "subnet %I", cilong
);
1879 while (p
< optend
) {
1881 printer(arg
, " %.2x", code
);
1889 if (len
> 0 && *p
>= ' ' && *p
< 0x7f) {
1891 print_string((char *)p
, len
, printer
, arg
);
1898 /* print the rest of the bytes in the packet */
1899 for (; len
> 0; --len
) {
1901 printer(arg
, " %.2x", code
);
1908 tcp_flag_decode(val
)
1911 static char buf
[32];
1933 * ip_active_pkt - see if this IP packet is worth bringing the link up for.
1934 * We don't bring the link up for IP fragments or for TCP FIN packets
1939 ip_active_pkt(pkt
, len
)
1944 struct protoent
*pep
;
1952 if (len
< IP_HDRLEN
) {
1953 dbglog("IP packet of length %d is not activity", len
);
1956 src
= get_ipsrc(pkt
);
1957 dst
= get_ipdst(pkt
);
1958 if ((get_ipoff(pkt
) & IP_OFFMASK
) != 0) {
1959 dbglog("IP fragment from %I->%I is not activity", src
, dst
);
1962 val
= get_ipproto(pkt
);
1963 if (val
!= IPPROTO_TCP
) {
1965 if ((pep
= getprotobynumber(val
)) != NULL
) {
1968 (void) slprintf(buf
, sizeof (buf
), "IP proto %d", val
);
1971 info("%s from %I->%I is activity", cp
, src
, dst
);
1975 hlen
= get_iphl(pkt
) * 4;
1976 if (len
< hlen
+ TCP_HDRLEN
) {
1977 dbglog("Bad TCP length %d<%d+%d %I->%I is not activity", len
, hlen
,
1978 TCP_HDRLEN
, src
, dst
);
1982 val
= get_tcpflags(tcp
);
1983 hlen
+= get_tcpoff(tcp
) * 4;
1984 if ((val
& TH_FIN
) != 0 && len
== hlen
) {
1985 dbglog("Empty TCP FIN %I->%I is not activity", src
, dst
);
1988 info("TCP %d data %s%I->%I is activity", len
- hlen
,
1989 tcp_flag_decode(get_tcpflags(tcp
)), src
, dst
);
1994 ipcp_print_stat(unit
, strptr
)
1998 ipcp_options
*go
= &ipcp_gotoptions
[unit
];
1999 ipcp_options
*ho
= &ipcp_hisoptions
[unit
];
2000 char *proto_name
= ipcp_protent
.name
;
2002 if (!ipcp_protent
.enabled_flag
) {
2003 (void) flprintf(strptr
, "%s disabled\n", proto_name
);
2007 (void) flprintf(strptr
, "%s state: %s", proto_name
,
2008 fsm_state(ipcp_fsm
[unit
].state
));
2009 (void) flprintf(strptr
, "%s local %I remote %I", proto_name
, go
->ouraddr
,