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.2 2006/05/31 09:34:26 andylin 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;
75 /* framemax = lcp_allowoptions[0].mru;
76 if (framemax < PPP_MRU) */
78 framemax += PPP_HDRLEN + PPP_FCSLEN;
79 frame = malloc(framemax);
88 netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU));
89 #if defined(INCLUDE_MTU_LAN_PPP)
90 ppp_send_config(0, lcp_allowoptions[0].mru, (u_int32_t) 0, 0, 0);
92 ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
94 #if defined(INCLUDE_MTU_LAN_PPP)
95 ppp_recv_config(0, lcp_allowoptions[0].mru, (u_int32_t) 0, 0, 0);
97 ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0);
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)))
115 * demand_block - set each network protocol to block further packets.
121 struct protent *protp;
123 for (i = 0; (protp = protocols[i]) != NULL; ++i)
124 if (protp->enabled_flag && protp->demand_conf != NULL)
125 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE);
130 * demand_discard - set each network protocol to discard packets
136 struct packet *pkt, *nextpkt;
138 struct protent *protp;
140 for (i = 0; (protp = protocols[i]) != NULL; ++i)
141 if (protp->enabled_flag && protp->demand_conf != NULL)
142 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR);
145 /* discard all saved packets */
146 for (pkt = pend_q; pkt != NULL; pkt = nextpkt) {
158 * demand_unblock - set each enabled network protocol to pass packets.
164 struct protent *protp;
166 for (i = 0; (protp = protocols[i]) != NULL; ++i)
167 if (protp->enabled_flag && protp->demand_conf != NULL)
168 sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS);
172 * FCS lookup table as calculated by genfcstab.
174 static u_short fcstab[256] = {
175 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
176 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
177 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
178 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
179 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
180 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
181 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
182 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
183 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
184 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
185 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
186 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
187 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
188 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
189 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
190 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
191 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
192 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
193 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
194 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
195 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
196 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
197 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
198 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
199 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
200 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
201 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
202 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
203 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
204 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
205 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
206 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
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.
225 if (!escape_flag && !flush_flag
226 && framelen > 2 && fcs == PPP_GOODFCS) {
228 if (loop_frame((unsigned char *)frame, framelen))
242 } else if (c == PPP_ESCAPE) {
246 if (framelen >= framemax) {
250 frame[framelen++] = c;
251 fcs = PPP_FCS(fcs, c);
257 * loop_frame - given a frame obtained from the loopback,
258 * decide whether to bring up the link or not, and, if we want
259 * to transmit this frame later, put it on the pending queue.
260 * Return value is 1 if we need to bring up the link, 0 otherwise.
261 * We assume that the kernel driver has already applied the
262 * pass_filter, so we won't get packets it rejected.
263 * We apply the active_filter to see if we want this packet to
268 loop_frame(frame, len)
269 unsigned char *frame;
274 /**********************************************************
275 * Fix bug(494):Setup ppp is manual mode. Router hanged up *
276 * if user generated packets to WAN side and the PPP *
277 * connection is down. *
278 * Andy (2005/10/18) *
279 **************************************************/
280 extern int ppp_status;
281 if (ppp_manual && !ppp_status)// is manual mode and ppp is down
284 /* dbglog("from loop: %P", frame, len); */
285 if (len < PPP_HDRLEN)
287 if ((PPP_PROTOCOL(frame) & 0x8000) != 0)
288 return 0; /* shouldn't get any of these anyway */
289 if (!active_packet(frame, len))
292 pkt = (struct packet *) malloc(sizeof(struct packet) + len);
296 memcpy(pkt->data, frame, len);
300 pend_qtail->next = pkt;
307 * demand_rexmit - Resend all those frames which we got via the
308 * loopback, now that the real serial link is up.
314 struct packet *pkt, *prev, *nextpkt;
319 for (; pkt != NULL; pkt = nextpkt) {
321 if (PPP_PROTOCOL(pkt->data) == proto) {
322 output(0, pkt->data, pkt->length);
338 * Scan a packet to decide whether it is an "active" packet,
339 * that is, whether it is worth bringing up the link for.
342 active_packet(p, len)
347 struct protent *protp;
349 if (len < PPP_HDRLEN)
351 proto = PPP_PROTOCOL(p);
353 if (pass_filter.bf_len != 0
354 && bpf_filter(pass_filter.bf_insns, p, len, len) == 0)
356 if (active_filter.bf_len != 0
357 && bpf_filter(active_filter.bf_insns, p, len, len) == 0)
360 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
361 if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
362 if (!protp->enabled_flag)
364 if (protp->active_pkt == NULL)
366 return (*protp->active_pkt)(p, len);
369 return 0; /* not a supported protocol !!?? */