2 * demand.c - Support routines for demand-dialling.
4 * Copyright (c) 1996-2024 Paul Mackerras. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
19 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
21 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
23 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
24 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37 #include <sys/param.h>
38 #include <sys/types.h>
41 #include <sys/resource.h>
43 #include <sys/socket.h>
44 #ifdef PPP_WITH_FILTER
48 #include "pppd-private.h"
64 unsigned char data[1];
67 struct packet *pend_q;
68 struct packet *pend_qtail;
70 static int active_packet(unsigned char *, int);
73 * demand_conf - configure the interface for doing dial-on-demand.
79 struct protent *protp;
81 /* framemax = lcp_allowoptions[0].mru;
82 if (framemax < PPP_MRU) */
84 framemax += PPP_HDRLEN + PPP_FCSLEN;
85 frame = malloc(framemax);
94 ppp_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
95 if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0
96 || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0)
97 fatal("Couldn't set up demand-dialled PPP interface: %m");
99 #ifdef PPP_WITH_FILTER
100 set_filters(&pass_filter, &active_filter);
104 * Call the demand_conf procedure for each protocol that's got one.
106 for (i = 0; (protp = protocols[i]) != NULL; ++i)
107 if (protp->enabled_flag && protp->demand_conf != NULL)
108 if (!((*protp->demand_conf)(0)))
114 * demand_block - set each network protocol to block further packets.
120 struct protent *protp;
122 for (i = 0; (protp = protocols[i]) != NULL; ++i)
123 if (protp->enabled_flag && protp->demand_conf != NULL)
124 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
129 * demand_discard - set each network protocol to discard packets
135 struct packet *pkt, *nextpkt;
137 struct protent *protp;
139 for (i = 0; (protp = protocols[i]) != NULL; ++i)
140 if (protp->enabled_flag && protp->demand_conf != NULL)
141 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
144 /* discard all saved packets */
145 for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
157 * demand_unblock - set each enabled network protocol to pass packets.
163 struct protent *protp;
165 for (i = 0; (protp = protocols[i]) != NULL; ++i)
166 if (protp->enabled_flag && protp->demand_conf != NULL)
167 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
171 * FCS lookup table as calculated by genfcstab.
173 static u_short fcstab[256] = {
174 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
175 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
176 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
177 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
178 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
179 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
180 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
181 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
182 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
183 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
184 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
185 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
186 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
187 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
188 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
189 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
190 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
191 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
192 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
193 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
194 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
195 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
196 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
197 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
198 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
199 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
200 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
201 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
202 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
203 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
204 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
205 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
207 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
210 * loop_chars - process characters received from the loopback.
211 * Calls loop_frame when a complete frame has been accumulated.
212 * Return value is 1 if we need to bring up the link, 0 otherwise.
215 loop_chars(unsigned char *p, int n)
223 if (!escape_flag && !flush_flag
224 && framelen > 2 && fcs == PPP_GOODFCS) {
226 if (loop_frame((unsigned char *)frame, framelen))
240 } else if (c == PPP_ESCAPE) {
244 if (framelen >= framemax) {
248 frame[framelen++] = c;
249 fcs = PPP_FCS(fcs, c);
255 * loop_frame - given a frame obtained from the loopback,
256 * decide whether to bring up the link or not, and, if we want
257 * to transmit this frame later, put it on the pending queue.
258 * Return value is 1 if we need to bring up the link, 0 otherwise.
259 * We assume that the kernel driver has already applied the
260 * pass_filter, so we won't get packets it rejected.
261 * We apply the active_filter to see if we want this packet to
265 loop_frame(unsigned char *frame, int len)
269 /* dbglog("from loop: %P", frame, len); */
270 if (len < PPP_HDRLEN)
272 if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
273 return 0; /* shouldn't get any of these anyway */
274 if (!active_packet(frame, len))
277 pkt = (struct packet *) malloc(sizeof(struct packet) + len);
281 memcpy(pkt->data, frame, len);
285 pend_qtail->next = pkt;
292 * demand_rexmit - Resend all those frames which we got via the
293 * loopback, now that the real serial link is up.
296 demand_rexmit(int proto)
298 struct packet *pkt, *prev, *nextpkt;
303 for (; pkt != NULL; pkt = nextpkt) {
305 if (PPP_PROTOCOL(pkt->data) == proto) {
306 output(0, pkt->data, pkt->length);
322 * Scan a packet to decide whether it is an "active" packet,
323 * that is, whether it is worth bringing up the link for.
326 active_packet(unsigned char *p, int len)
329 struct protent *protp;
331 if (len < PPP_HDRLEN)
333 proto = PPP_PROTOCOL(p);
334 #ifdef PPP_WITH_FILTER
335 p[0] = 1; /* outbound packet indicator */
336 if ((pass_filter.bf_len != 0
337 && bpf_filter(pass_filter.bf_insns, p, len, len) == 0)
338 || (active_filter.bf_len != 0
339 && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) {
345 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
346 if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
347 if (!protp->enabled_flag)
349 if (protp->active_pkt == NULL)
351 return (*protp->active_pkt)(p, len);
354 return 0; /* not a supported protocol !!?? */