2 * demand.c - Support routines for demand-dialling.
4 * Copyright (c) 1993 The Australian National University.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by the Australian National University. The name of the University
13 * may not be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 #define RCSID "$Id: demand.c,v 1.15 2001/03/08 05:14:26 paulus Exp $"
28 #include <sys/param.h>
29 #include <sys/types.h>
32 #include <sys/resource.h>
34 #include <sys/socket.h>
46 static const char rcsid[] = RCSID;
58 unsigned char data[1];
61 struct packet *pend_q;
62 struct packet *pend_qtail;
64 static int active_packet __P((unsigned char *, int));
67 * demand_conf - configure the interface for doing dial-on-demand.
73 struct protent *protp;
76 /* framemax = lcp_allowoptions[0].mru;
77 if (framemax < PPP_MRU) */
79 framemax += PPP_HDRLEN + PPP_FCSLEN;
80 frame = malloc(framemax);
89 netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
90 ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
91 ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
94 set_filters(&pass_filter, &active_filter);
98 * Call the demand_conf procedure for each protocol that's got one.
100 for (i = 0; (protp = protocols[i]) != NULL; ++i)
101 if (protp->enabled_flag && protp->demand_conf != NULL)
102 if (!((*protp->demand_conf)(0)))
108 * demand_block - set each network protocol to block further packets.
114 struct protent *protp;
116 for (i = 0; (protp = protocols[i]) != NULL; ++i)
117 if (protp->enabled_flag && protp->demand_conf != NULL)
118 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
123 * demand_discard - set each network protocol to discard packets
129 struct packet *pkt, *nextpkt;
131 struct protent *protp;
133 for (i = 0; (protp = protocols[i]) != NULL; ++i)
134 if (protp->enabled_flag && protp->demand_conf != NULL)
135 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
138 /* discard all saved packets */
139 for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
151 * demand_unblock - set each enabled network protocol to pass packets.
157 struct protent *protp;
159 for (i = 0; (protp = protocols[i]) != NULL; ++i)
160 if (protp->enabled_flag && protp->demand_conf != NULL)
161 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
165 * FCS lookup table as calculated by genfcstab.
167 static u_short fcstab[256] = {
168 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
169 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
170 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
171 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
172 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
173 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
174 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
175 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
176 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
177 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
178 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
179 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
180 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
181 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
182 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
183 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
184 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
185 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
186 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
187 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
188 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
189 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
190 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
191 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
192 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
193 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
194 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
195 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
196 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
197 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
198 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
199 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
203 * loop_chars - process characters received from the loopback.
204 * Calls loop_frame when a complete frame has been accumulated.
205 * Return value is 1 if we need to bring up the link, 0 otherwise.
218 if (!escape_flag && !flush_flag
219 && framelen > 2 && fcs == PPP_GOODFCS) {
221 if (loop_frame((unsigned char *)frame, framelen))
235 } else if (c == PPP_ESCAPE) {
239 if (framelen >= framemax) {
243 frame[framelen++] = c;
244 fcs = PPP_FCS(fcs, c);
250 * loop_frame - given a frame obtained from the loopback,
251 * decide whether to bring up the link or not, and, if we want
252 * to transmit this frame later, put it on the pending queue.
253 * Return value is 1 if we need to bring up the link, 0 otherwise.
254 * We assume that the kernel driver has already applied the
255 * pass_filter, so we won't get packets it rejected.
256 * We apply the active_filter to see if we want this packet to
260 loop_frame(frame, len)
261 unsigned char *frame;
266 /* dbglog("from loop: %P", frame, len); */
267 if (len < PPP_HDRLEN)
269 if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
270 return 0; /* shouldn't get any of these anyway */
271 if (!active_packet(frame, len))
274 pkt = (struct packet *) malloc(sizeof(struct packet) + len);
278 memcpy(pkt->data, frame, len);
282 pend_qtail->next = pkt;
289 * demand_rexmit - Resend all those frames which we got via the
290 * loopback, now that the real serial link is up.
296 struct packet *pkt, *prev, *nextpkt;
301 for (; pkt != NULL; pkt = nextpkt) {
303 if (PPP_PROTOCOL(pkt->data) == proto) {
304 output(0, pkt->data, pkt->length);
320 * Scan a packet to decide whether it is an "active" packet,
321 * that is, whether it is worth bringing up the link for.
324 active_packet(p, len)
329 struct protent *protp;
331 if (len < PPP_HDRLEN)
333 proto = PPP_PROTOCOL(p);
335 if (pass_filter.bf_len != 0
336 && bpf_filter(pass_filter.bf_insns, p, len, len) == 0)
338 if (active_filter.bf_len != 0
339 && bpf_filter(active_filter.bf_insns, p, len, len) == 0)
342 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
343 if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
344 if (!protp->enabled_flag)
346 if (protp->active_pkt == NULL)
348 return (*protp->active_pkt)(p, len);
351 return 0; /* not a supported protocol !!?? */