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.
19 * $FreeBSD: src/usr.sbin/pppd/demand.c,v 1.5 1999/08/28 01:19:02 peter Exp $
20 * $DragonFly: src/usr.sbin/pppd/demand.c,v 1.4 2005/11/24 23:42:54 swildner Exp $
30 #include <sys/param.h>
31 #include <sys/types.h>
34 #include <sys/resource.h>
36 #include <sys/socket.h>
58 unsigned char data
[1];
61 struct packet
*pend_q
;
62 struct packet
*pend_qtail
;
64 static int active_packet(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 ppp_send_config(0, PPP_MRU
, (u_int32_t
) 0, 0, 0);
89 ppp_recv_config(0, PPP_MRU
, (u_int32_t
) 0, 0, 0);
92 set_filters(&pass_filter
, &active_filter
);
96 * Call the demand_conf procedure for each protocol that's got one.
98 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
99 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
100 if (!((*protp
->demand_conf
)(0)))
106 * demand_block - set each network protocol to block further packets.
112 struct protent
*protp
;
114 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
115 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
116 sifnpmode(0, protp
->protocol
& ~0x8000, NPMODE_QUEUE
);
121 * demand_discard - set each network protocol to discard packets
127 struct packet
*pkt
, *nextpkt
;
129 struct protent
*protp
;
131 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
132 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
133 sifnpmode(0, protp
->protocol
& ~0x8000, NPMODE_ERROR
);
136 /* discard all saved packets */
137 for (pkt
= pend_q
; pkt
!= NULL
; pkt
= nextpkt
) {
149 * demand_unblock - set each enabled network protocol to pass packets.
155 struct protent
*protp
;
157 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
158 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
159 sifnpmode(0, protp
->protocol
& ~0x8000, NPMODE_PASS
);
163 * FCS lookup table as calculated by genfcstab.
165 static u_short fcstab
[256] = {
166 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
167 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
168 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
169 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
170 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
171 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
172 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
173 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
174 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
175 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
176 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
177 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
178 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
179 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
180 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
181 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
182 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
183 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
184 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
185 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
186 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
187 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
188 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
189 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
190 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
191 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
192 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
193 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
194 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
195 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
196 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
197 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
201 * loop_chars - process characters received from the loopback.
202 * Calls loop_frame when a complete frame has been accumulated.
203 * Return value is 1 if we need to bring up the link, 0 otherwise.
206 loop_chars(unsigned char *p
, int n
)
214 if (!escape_flag
&& !flush_flag
215 && framelen
> 2 && fcs
== PPP_GOODFCS
) {
217 if (loop_frame(frame
, framelen
))
231 } else if (c
== PPP_ESCAPE
) {
235 if (framelen
>= framemax
) {
239 frame
[framelen
++] = c
;
240 fcs
= PPP_FCS(fcs
, c
);
246 * loop_frame - given a frame obtained from the loopback,
247 * decide whether to bring up the link or not, and, if we want
248 * to transmit this frame later, put it on the pending queue.
249 * Return value is 1 if we need to bring up the link, 0 otherwise.
250 * We assume that the kernel driver has already applied the
251 * pass_filter, so we won't get packets it rejected.
252 * We apply the active_filter to see if we want this packet to
256 loop_frame(unsigned char *frame
, int len
)
260 /* log_packet(frame, len, "from loop: ", LOG_DEBUG); */
261 if (len
< PPP_HDRLEN
)
263 if ((PPP_PROTOCOL(frame
) & 0x8000) != 0)
264 return 0; /* shouldn't get any of these anyway */
265 if (!active_packet(frame
, len
))
268 pkt
= (struct packet
*) malloc(sizeof(struct packet
) + len
);
272 memcpy(pkt
->data
, frame
, len
);
276 pend_qtail
->next
= pkt
;
283 * demand_rexmit - Resend all those frames which we got via the
284 * loopback, now that the real serial link is up.
287 demand_rexmit(int proto
)
289 struct packet
*pkt
, *prev
, *nextpkt
;
294 for (; pkt
!= NULL
; pkt
= nextpkt
) {
296 if (PPP_PROTOCOL(pkt
->data
) == proto
) {
297 output(0, pkt
->data
, pkt
->length
);
313 * Scan a packet to decide whether it is an "active" packet,
314 * that is, whether it is worth bringing up the link for.
317 active_packet(unsigned char *p
, int len
)
320 struct protent
*protp
;
322 if (len
< PPP_HDRLEN
)
324 proto
= PPP_PROTOCOL(p
);
326 if (active_filter
.bf_len
!= 0
327 && bpf_filter(active_filter
.bf_insns
, frame
, len
, len
) == 0)
330 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
) {
331 if (protp
->protocol
< 0xC000 && (protp
->protocol
& ~0x8000) == proto
) {
332 if (!protp
->enabled_flag
)
334 if (protp
->active_pkt
== NULL
)
336 return (*protp
->active_pkt
)(p
, len
);
339 return 0; /* not a supported protocol !!?? */