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.
21 static char rcsid
[] = "$FreeBSD$";
31 #include <sys/param.h>
32 #include <sys/types.h>
35 #include <sys/resource.h>
37 #include <sys/socket.h>
59 unsigned char data
[1];
62 struct packet
*pend_q
;
63 struct packet
*pend_qtail
;
65 static int active_packet(unsigned char *, int);
68 * demand_conf - configure the interface for doing dial-on-demand.
74 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 ppp_send_config(0, PPP_MRU
, (u_int32_t
) 0, 0, 0);
90 ppp_recv_config(0, PPP_MRU
, (u_int32_t
) 0, 0, 0);
93 set_filters(&pass_filter
, &active_filter
);
97 * Call the demand_conf procedure for each protocol that's got one.
99 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
100 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
101 if (!((*protp
->demand_conf
)(0)))
107 * demand_block - set each network protocol to block further packets.
113 struct protent
*protp
;
115 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
116 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
117 sifnpmode(0, protp
->protocol
& ~0x8000, NPMODE_QUEUE
);
122 * demand_discard - set each network protocol to discard packets
128 struct packet
*pkt
, *nextpkt
;
130 struct protent
*protp
;
132 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
133 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
134 sifnpmode(0, protp
->protocol
& ~0x8000, NPMODE_ERROR
);
137 /* discard all saved packets */
138 for (pkt
= pend_q
; pkt
!= NULL
; pkt
= nextpkt
) {
150 * demand_unblock - set each enabled network protocol to pass packets.
156 struct protent
*protp
;
158 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
159 if (protp
->enabled_flag
&& protp
->demand_conf
!= NULL
)
160 sifnpmode(0, protp
->protocol
& ~0x8000, NPMODE_PASS
);
164 * FCS lookup table as calculated by genfcstab.
166 static u_short fcstab
[256] = {
167 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
168 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
169 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
170 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
171 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
172 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
173 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
174 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
175 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
176 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
177 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
178 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
179 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
180 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
181 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
182 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
183 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
184 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
185 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
186 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
187 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
188 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
189 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
190 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
191 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
192 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
193 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
194 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
195 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
196 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
197 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
198 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
202 * loop_chars - process characters received from the loopback.
203 * Calls loop_frame when a complete frame has been accumulated.
204 * Return value is 1 if we need to bring up the link, 0 otherwise.
217 if (!escape_flag
&& !flush_flag
218 && framelen
> 2 && fcs
== PPP_GOODFCS
) {
220 if (loop_frame(frame
, framelen
))
234 } else if (c
== PPP_ESCAPE
) {
238 if (framelen
>= framemax
) {
242 frame
[framelen
++] = c
;
243 fcs
= PPP_FCS(fcs
, c
);
249 * loop_frame - given a frame obtained from the loopback,
250 * decide whether to bring up the link or not, and, if we want
251 * to transmit this frame later, put it on the pending queue.
252 * Return value is 1 if we need to bring up the link, 0 otherwise.
253 * We assume that the kernel driver has already applied the
254 * pass_filter, so we won't get packets it rejected.
255 * We apply the active_filter to see if we want this packet to
259 loop_frame(frame
, len
)
260 unsigned char *frame
;
265 /* log_packet(frame, len, "from loop: ", LOG_DEBUG); */
266 if (len
< PPP_HDRLEN
)
268 if ((PPP_PROTOCOL(frame
) & 0x8000) != 0)
269 return 0; /* shouldn't get any of these anyway */
270 if (!active_packet(frame
, len
))
273 pkt
= (struct packet
*) malloc(sizeof(struct packet
) + len
);
277 memcpy(pkt
->data
, frame
, len
);
281 pend_qtail
->next
= pkt
;
288 * demand_rexmit - Resend all those frames which we got via the
289 * loopback, now that the real serial link is up.
295 struct packet
*pkt
, *prev
, *nextpkt
;
300 for (; pkt
!= NULL
; pkt
= nextpkt
) {
302 if (PPP_PROTOCOL(pkt
->data
) == proto
) {
303 output(0, pkt
->data
, pkt
->length
);
319 * Scan a packet to decide whether it is an "active" packet,
320 * that is, whether it is worth bringing up the link for.
323 active_packet(p
, len
)
328 struct protent
*protp
;
330 if (len
< PPP_HDRLEN
)
332 proto
= PPP_PROTOCOL(p
);
334 if (active_filter
.bf_len
!= 0
335 && bpf_filter(active_filter
.bf_insns
, frame
, len
, len
) == 0)
338 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
) {
339 if (protp
->protocol
< 0xC000 && (protp
->protocol
& ~0x8000) == proto
) {
340 if (!protp
->enabled_flag
)
342 if (protp
->active_pkt
== NULL
)
344 return (*protp
->active_pkt
)(p
, len
);
347 return 0; /* not a supported protocol !!?? */