Project

General

Profile

Download (18.7 KB) Statistics
| Branch: | Tag: | Revision:
1 061f78b1 Bill Marquette
<?php
2
/* $Id$ */
3
/*
4 afb5973f Bill Marquette
	shaper.inc
5 0e16b9ca Scott Ullrich
	Copyright (C) 2004-2006 Scott Ullrich
6
	Copyright (C) 2005-2006 Bill Marquette
7 afb5973f Bill Marquette
	All rights reserved.
8
9
	Redistribution and use in source and binary forms, with or without
10
	modification, are permitted provided that the following conditions are met:
11
12
	1. Redistributions of source code must retain the above copyright notice,
13
	this list of conditions and the following disclaimer.
14
15
	2. Redistributions in binary form must reproduce the above copyright
16
	notice, this list of conditions and the following disclaimer in the
17
	documentation and/or other materials provided with the distribution.
18
19
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
	POSSIBILITY OF SUCH DAMAGE.
29 061f78b1 Bill Marquette
30
*/
31
32
/* include all configuration functions */
33
require_once("functions.inc");
34
require_once("pkg-utils.inc");
35
require_once("notices.inc");
36
37
function find_default_queue($interface) {
38
	global $config, $queue_cache;
39
	$qconfig = $config;
40
41
	/* quick return if we've already seen the default queue for this interface */
42
	if (isset($queue_cache['defq'][$interface]))
43
	return $queue_cache['defq'][$interface];
44
45
	if (is_array($qconfig['shaper']['queue'])) {
46
		foreach ($qconfig['shaper']['queue'] as $queue) {
47
			if(isset($queue['defaultqueue']) and ($queue['defaultqueue'] <> "")) {
48
				/* If this is a child queue */
49
				if(isset($queue['attachtoqueue'])) {
50
					if(is_subqueue_used_on_interface($queue['attachtoqueue'], $interface)) {
51
						$queue_cache['defq'][$interface] = $queue['name'];
52
						return $queue['name'];
53
					}
54
				} else {
55
					$queue_cache['defq'][$interface] = $queue['name'];
56
					return $queue['name'];
57
				}
58
			}
59
		}
60
	}
61
62
	/* unreachable */
63
	return null;
64
}
65
66
function get_ack_queue($interface) {
67
	global $config, $queue_cache;
68
69
	/* quick return if we've already seen the ack queue for this interface */
70
	if (isset($queue_cache['ackq'][$interface]))
71
	return $queue_cache['ackq'][$interface];
72
73
	$qconfig = $config;
74
75
	if (is_array($qconfig['shaper']['queue'])) {
76
		foreach ($qconfig['shaper']['queue'] as $queue) {
77
			if(isset($queue['ack']))
78
			if(isset($queue['attachtoqueue']))
79
			if(is_subqueue_used_on_interface($queue['attachtoqueue'], $interface)) {
80
				/* Add to cache */
81
				$queue_cache['ackq'][$interface] = $queue['name'];
82
				return $queue['name'];
83
			}
84
		}
85
	}
86
	/* unreachable */
87
	return null;
88
}
89
90
function filter_generate_altq_queues($altq_ints) {
91
	global $config;
92
	$altq_rules = "";
93
	if (is_array($config['shaper']['queue'])) {
94
		foreach ($config['shaper']['queue'] as $rule) {
95 9b3b1acc Scott Ullrich
			update_filter_reload_status("Generating ALTQ queue {$rule['descr']}...");
96 061f78b1 Bill Marquette
			$options = "";
97
			// check to make sure we're actually using this queue.
98
			//if(stristr($altq_ints, $rule['name']) !== FALSE) {
99
			$altq_rules .= "queue {$rule['name']} ";
100
			if (isset($rule['bandwidth']) and $rule['bandwidth'] <> "")
101
			$altq_rules .= "bandwidth {$rule['bandwidth']}{$rule['bandwidthtype']} ";
102
			if (isset($rule['priority']) and $rule['priority'] <> "")
103
			$altq_rules .= "priority {$rule['priority']} ";
104 f1227b84 Scott Ullrich
			if (isset($rule['qlimit']) and $rule['qlimit'] <> "")
105
			$altq_rules .= "qlimit {$rule['qlimit']} ";
106 061f78b1 Bill Marquette
			if(isset($rule['red']) and $rule['red'] <> "")
107
			$options .= " red";
108
			if(isset($rule['borrow']) and $rule['borrow'] <> "")
109
			$options .= " borrow";
110
			if(isset($rule['ecn']) and $rule['ecn'] <> "")
111
			$options .= " ecn";
112
			if(isset($rule['rio']) and $rule['rio'] <> "")
113
			$options .= " rio";
114
			if(isset($rule['defaultqueue']) and $rule['defaultqueue'] <> "")
115
			$options .= " default";
116
			if(isset($rule['upperlimit']) and $rule['upperlimit'] <> "") {
117 e295675f Scott Ullrich
				if ($rule['upperlimit1'] <> "")
118
					$options .= " upperlimit({$rule['upperlimit1']} {$rule['upperlimit2']} {$rule['upperlimit3']})";
119
				else
120
					$options .= " upperlimit {$rule['upperlimit3']}";
121 061f78b1 Bill Marquette
			}
122
			if(isset($rule['linkshare']) and $rule['linkshare'] <> "") {
123 e295675f Scott Ullrich
				if ($rule['linkshare1'] <> "")
124
					$options .= " linkshare({$rule['linkshare1']} {$rule['linkshare2']} {$rule['linkshare3']})";
125
				else
126
					$options .= " linkshare {$rule['linkshare3']}";
127 061f78b1 Bill Marquette
			}
128
			if(isset($rule['realtime']) and $rule['realtime'] <> "") {
129 e295675f Scott Ullrich
				if ($rule['realtime1'] <> "")
130
					$options .= " realtime({$rule['realtime1']} {$rule['realtime2']} {$rule['realtime3']})";
131
				else
132
					 $options .= " realtime {$rule['realtime3']}";
133 061f78b1 Bill Marquette
			}
134 7bdf53c9 Scott Ullrich
			$scheduler_type = $config['shaper']['schedulertype'];
135 4f9a3d3b Scott Ullrich
			$altq_rules .= "{$scheduler_type} ";
136 061f78b1 Bill Marquette
			if($options)
137
				$altq_rules .= "( {$options} )";
138
			$fsq="";
139
			foreach($config['shaper']['queue'] as $q) {
140
				if($q['attachtoqueue'] == $rule['name']) {
141
					if($fsq == "") {
142
						$altq_rules .= "{ ";
143
					}
144
					else if($fsq == "1") {
145
						$altq_rules .= ", ";
146
					}
147
					$altq_rules .= $q['name'];
148
					$fsq = "1";
149
				}
150
			}
151
			if($fsq == "1")
152
			$altq_rules .= " }";
153
			$altq_rules .= "\n";
154
			//}
155
		}
156
	}
157
	return $altq_rules;
158
}
159
160
/* Find a queue that's attached to this one and see if that queue is used on this interface */
161
function is_subqueue_used_on_interface($queuename, $interface) {
162
	global $config;
163
	$qconfig = $config;
164
	if (!is_array($qconfig['shaper']['queue'])) return 0;
165
166
	foreach ($qconfig['shaper']['queue'] as $queue) {
167 b7ff5e40 Scott Ullrich
		if($queue['attachtoqueue'] == $queuename) {
168
			/* recurse if we're a parent queue */
169
			if ($queue['parentqueue'] == "on") {
170
				return is_subqueue_used_on_interface($queue['name'], $interface);
171
			}
172
173
			/* If we're not a parent check to see if the queue is used on this interface */
174
			$subqueue_interface = filter_is_queue_being_used_on_interface($queue['name'], $interface);
175
			if ($subqueue_interface != ""){
176
				return 1;
177
			}
178 061f78b1 Bill Marquette
		}
179
	}
180
	return 0;
181
}
182
183 191ed731 Scott Ullrich
function filter_is_queue_being_used_on_interface($queuename, $interface, $direction = 'in') {
184 061f78b1 Bill Marquette
	global $config;
185
	$lconfig = $config;
186
187
	if(!is_array($lconfig['shaper']['rule'])) return null;
188
	foreach($lconfig['shaper']['rule'] as $rule) {
189 191ed731 Scott Ullrich
		$q  = $direction . 'queue';
190
		$if = $direction . '-interface';
191
		if(($rule[$q] == $queuename && $rule[$if] == $interface))
192 061f78b1 Bill Marquette
		return $interface;
193
	}
194
	return null;
195
}
196
197
function filter_setup_altq_interfaces() {
198
	global $config;
199
	$altq_rules  = "";
200
	$queue_names = "";
201
	$is_first = "";
202
203
	if(!is_array($config['shaper']['queue'])) return null;
204
205
	$ifdescrs = array('wan', 'lan');
206
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
207
		$ifdescrs[] = "opt" . $j;
208
	}
209
	foreach ($ifdescrs as $ifdescr => $ifname) {
210
211
		$queue_names = "";
212
		$is_first = "";
213
214 b7ff5e40 Scott Ullrich
		$queue_names = find_root_queue($ifname);
215 061f78b1 Bill Marquette
216
		if($queue_names <> ""){
217
			$altq_rules .= "altq on {$config['interfaces'][$ifname]['if']} ";
218 f1227b84 Scott Ullrich
			$bandwidth_arr = get_queue_bandwidth($queue_names);
219
			$bandwidth = "bandwidth {$bandwidth_arr['bandwidth']}{$bandwidth_arr['bandwidthtype']}";
220 061f78b1 Bill Marquette
			$altq_rules .= "{$config['shaper']['schedulertype']} {$bandwidth} ";
221
			$altq_rules .= "queue { {$queue_names} }";
222
		}
223
		$altq_rules .= "\n";
224
225
	}
226
	return $altq_rules;
227
}
228
229 f1227b84 Scott Ullrich
230
231 b7ff5e40 Scott Ullrich
/* Find the root queue for an interface */
232
function find_root_queue($ifname) {
233
	global $config;
234 5ca160b3 Scott Ullrich
	$queue_names = "";
235 b7ff5e40 Scott Ullrich
	foreach ($config['shaper']['queue'] as $queue) {
236
		$rule_interface = "";
237
		$q = $queue;
238
		/* if we're a parentqueue and aren't attached to another queue we're probably a root */
239
		if ((isset($q['parentqueue']) && $q['parentqueue'] <> "") && (!isset($q['attachtoqueue']) || $q['attachtoqueue'] == "")) {
240
			/* Confirm that this is a valid queue for this interface */
241
			$rule_interface = is_subqueue_used_on_interface($q['name'], $ifname);
242
			if ($rule_interface == 1) {
243 f1227b84 Scott Ullrich
				if (strlen($queue_names) > 0)
244
					$queue_names .= " ";
245 b7ff5e40 Scott Ullrich
				$queue_names .= $q['name'];
246
			}
247
		}
248
	}
249
	return $queue_names;
250
}
251
252 f1227b84 Scott Ullrich
function get_queue_bandwidth($name) {
253
	global $config;
254
	foreach ($config['shaper']['queue'] as $queue) {
255
		if ($queue['name'] == $name) {
256
			return array(
257
				'bandwidth' => $queue['bandwidth'],
258
				'bandwidthtype' => $queue['bandwidthtype']
259
			);
260
		}
261
	}
262
}
263
264 061f78b1 Bill Marquette
function is_queue_attached_children($name) {
265
	global $config;
266
	if (!is_array($config['shaper']['queue'])) return 0;
267
	foreach ($config['shaper']['queue'] as $queue) {
268
		if($queue['attachtoqueue'] == $name) return 1;
269
	}
270
	return 0;
271
}
272
273
function queue_interface_recursive($queuename) {
274
	global $config;
275
	foreach($config['shaper']['queue'] as $queue) {
276
		if($queue['attachtoqueue'] == $queuename) {
277
			$status = queue_interface_recursive($queue['name']);
278
			if($status <> "") return $status;
279
		}
280
		foreach($config['shaper']['rule'] as $rule) {
281
			if($rule['inqueue'] == $queuename)
282 e295675f Scott Ullrich
			return $rule['in-interface'];
283 061f78b1 Bill Marquette
		}
284
	}
285
286
	/* unreachable */
287
	return null;
288
}
289
290
function is_subqueue($name) {
291
	global $config;
292
	$queues = $config['shaper']['queue']; /* must assign to keep from corrupting in memory $config */
293
	if (!is_array($queues)) return 0;
294
	foreach ($queues as $queue) {
295
		if($queue['attachtoqueue'] == $name) return 1;
296
	}
297
	return 0;
298
}
299
300
function filter_altq_get_queuename($queuenum) {
301
	global $config;
302
	$x=0;
303
	foreach($config['shaper']['queue'] as $rule) {
304
		if($x == $queuenum)
305
		return $rule['name'];
306
		$x++;
307
	}
308
	/* unreachable */
309
	return null;
310
}
311
312
function filter_generate_pf_altq_rules() {
313
	/* I don't think we're in IPFW anymore Toto */
314 767a716e Scott Ullrich
	$i = 0;
315 0a33f73e Scott Ullrich
316 62a48760 Scott Ullrich
	global $config, $g, $tcpflags;
317 061f78b1 Bill Marquette
318
	$lancfg = $config['interfaces']['lan'];
319
	$pptpdcfg = $config['pptpd'];
320
	$pppoecfg = $config['pppoe'];
321
322
	$lanif = $lancfg['if'];
323
	$wanif = get_real_wan_interface();
324
325
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
326
	$lansn = $lancfg['subnet'];
327
328
	/* optional interfaces */
329
	$optcfg = array();
330
	generate_optcfg_array($optcfg);
331
332
	if ($pptpdcfg['mode'] == "server") {
333
		$pptpsa = $pptpdcfg['remoteip'];
334
		$pptpsn = $g['pptp_subnet'];
335
		if($config['pptp']['pptp_subnet'] <> "")
336
		$pptpsn = $config['pptp']['pptp_subnet'];
337
	}
338
339
	if ($pppoecfg['mode'] == "server") {
340
		$pppoesa = $pppoecfg['remoteip'];
341
		$pppoesn = $g['pppoe_subnet'];
342
		if($config['pppoe']['pppoe_subnet'] <> "")
343
		$pppoesn = $config['pppoe']['pppoe_subnet'];
344
	}
345
346
	/* generate rules */
347
	if (isset($config['shaper']['rule']))
348
	foreach ($config['shaper']['rule'] as $rule) {
349
350
		/* don't include disabled rules */
351
		if (isset($rule['disabled'])) {
352
			$i++;
353
			continue;
354
		}
355
356 146f99c8 Scott Ullrich
		update_filter_reload_status("Generating ALTQ rule {$rule['descr']}...");
357 0a33f73e Scott Ullrich
358 e295675f Scott Ullrich
		switch($rule['in-interface']) {
359 061f78b1 Bill Marquette
			case "pptp": /* does the rule deal with a PPTP interface? */
360
				if ($pptpdcfg['mode'] != "server") {
361
					if (($rule['source']['network'] == "pptp") ||
362
					($rule['destination']['network'] == "pptp")) {
363
						$i++;
364
						continue;
365
					}
366
				}
367
368
				$nif = $g['n_pptp_units'];
369
				if($config['pptp']['n_pptp_units'] <> "")
370
					$nif = $config['pptp']['n_pptp_units'];
371
372
				$ispptp = true;
373
				break;
374
375
			case "pppoe": /* does the rule deal with a PPPOE interface? */
376
				if ($pppoecfg['mode'] != "server") {
377
					if (($rule['source']['network'] == "pppoe") ||
378
					($rule['destination']['network'] == "pppoe")) {
379
						$i++;
380
						continue;
381
					}
382
				}
383
384
				$nif = $g['n_pppoe_units'];
385
				if($config['pppoe']['n_pppoe_units'] <> "")
386
					$nif = $config['pppoe']['n_pppoe_units'];
387
388
				$ispppoe = true;
389
				break;
390
			default:
391 e295675f Scott Ullrich
				if (strstr($rule['in-interface'], "opt")) {
392
					if (!array_key_exists($rule['in-interface'], $optcfg)) {
393 061f78b1 Bill Marquette
						$i++;
394
						continue;
395
					}
396
				}
397
				$nif = 1;
398
				$ispptp = false;
399
				$ispppoe = false;
400
		}
401
402
		if (strstr($rule['source']['network'], "opt")) {
403
			if (!array_key_exists($rule['source']['network'], $optcfg)) {
404
				$i++;
405
				continue;
406
			}
407
		}
408
		if (strstr($rule['destination']['network'], "opt")) {
409
			if (!array_key_exists($rule['destination']['network'], $optcfg)) {
410
				$i++;
411
				continue;
412
			}
413
		}
414
415
		/* check for unresolvable aliases */
416
		if ($rule['source']['address'] && !alias_expand($rule['source']['address'])) {
417
			$i++;
418
			continue;
419
		}
420
		if ($rule['destination']['address'] && !alias_expand($rule['destination']['address'])) {
421
			$i++;
422
			continue;
423
		}
424
425 fa000715 Scott Ullrich
		$lanip = find_interface_ip($config['interfaces']['lan']['if']);
426
		$wanip = find_interface_ip(get_real_wan_interface());
427
428 061f78b1 Bill Marquette
		for ($iif = 0; $iif < $nif; $iif++) {
429 0f0c6a9e Scott Ullrich
			$direction = 'in';
430
			$line = "pass {$direction} on ";
431
432
			if ($ispptp) {
433
				$line .= " ng" . ($iif+1);
434 0a33f73e Scott Ullrich
			}
435 0f0c6a9e Scott Ullrich
			else if($ispppoe) {
436
				$line .= " ng" . ($iif+1);
437 0a33f73e Scott Ullrich
			}
438 0f0c6a9e Scott Ullrich
			else {
439 97fadf79 Scott Ullrich
				$friendly_desc = convert_friendly_interface_to_friendly_descr($rule['in-interface']);
440
				$line .= " \${$friendly_desc} ";
441 0f0c6a9e Scott Ullrich
			}
442 0a33f73e Scott Ullrich
443 0f0c6a9e Scott Ullrich
			/* get protocol */
444
			$proto = $rule['protocol'];
445
			if (isset($proto)) {
446
				$line .= "proto {$proto} ";
447
			}
448 061f78b1 Bill Marquette
449 0f0c6a9e Scott Ullrich
			/* get source address */
450
			if (isset($rule['source']['any'])) {
451
				$src = "any";
452
			} else if ($rule['source']['network']) {
453 03101b55 Scott Ullrich
				if (stristr($rule['source']['network'], "opt") == true) {
454 0f0c6a9e Scott Ullrich
					$src = $optcfg[$rule['source']['network']]['sa'] . "/" .
455 03101b55 Scott Ullrich
						$optcfg[$rule['source']['network']]['sn'];
456 061f78b1 Bill Marquette
				} else {
457 0f0c6a9e Scott Ullrich
					switch ($rule['source']['network']) {
458 fa000715 Scott Ullrich
						case 'wanip':
459
							$src = $wanip;
460
							break;
461
						case 'lanip':
462
							$src = $lanip;
463
							break;
464 0f0c6a9e Scott Ullrich
						case 'lan':
465 03101b55 Scott Ullrich
							$src = "$lansa/$lansn";
466
							break;
467 0f0c6a9e Scott Ullrich
						case 'pptp':
468 03101b55 Scott Ullrich
							$src = "$pptpsa/$pptpsn";
469
							break;
470 0f0c6a9e Scott Ullrich
						case 'pppoe':
471 03101b55 Scott Ullrich
							$src = "$pppoesa/$pppoesn";
472
							break;
473 061f78b1 Bill Marquette
					}
474
				}
475 0f0c6a9e Scott Ullrich
			} else if ($rule['source']['address']) {
476
				$src = alias_expand($rule['source']['address']);
477
				if(!$src)
478
					$src = $rule['source']['address'];
479
			}
480 061f78b1 Bill Marquette
481 0f0c6a9e Scott Ullrich
			if (!$src) {
482
				printf("No source address found in rule $i\n");
483
				break;
484
			}
485 061f78b1 Bill Marquette
486 0f0c6a9e Scott Ullrich
			if (isset($rule['source']['not'])) {
487 0a33f73e Scott Ullrich
488
				/*pf is not really happy with this sexy ($src = "!{$src}";) approach of
489 2f038c0b Scott Ullrich
				 * negating a list or macro. So we have to write out a ! on each entry.
490 0a33f73e Scott Ullrich
				 */
491 2f038c0b Scott Ullrich
492 0a33f73e Scott Ullrich
				/* not very happy with this! but it beats copying this section to
493 2f038c0b Scott Ullrich
				 * several places.
494
				 */
495
				$alias = alias_expand(substr($src, 1));
496 0a33f73e Scott Ullrich
497 2f038c0b Scott Ullrich
				if(isset($alias) && stristr($alias, "$")) {
498
					$alias = alias_expand_value(substr($src, 1));
499
					$src = "{";
500
					foreach(preg_split("/[\s]+/", $alias) as $item) {
501
						if($item != "") {
502
							$src .= " !{$item}";
503
						}
504
					}
505
					$src .= " }";
506
				}
507
				else {
508
					$src = "!{$src}";
509
				}
510 0f0c6a9e Scott Ullrich
			}
511
			$line .= "from {$src} ";
512 0a33f73e Scott Ullrich
513 0f0c6a9e Scott Ullrich
			/* get source port */
514
			if (!isset($rule['protocol']) || in_array($rule['protocol'], array("tcp","udp"))) {
515
				if ($rule['source']['port']) {
516
					/*
517
					* Check to see if port is a alias.  If so grab it and
518
					* enclose it in { } to pass to pf.
519
					*
520
					* Otherwise combine the portrange into one if its only
521
					* one item.
522
					*/
523
					$src = alias_expand($rule['source']['port']);
524
					if($src <> "") {
525
						$line .= "port {$src}";
526 061f78b1 Bill Marquette
					} else {
527 0f0c6a9e Scott Ullrich
						$srcport = explode("-", $rule['source']['port']);
528
						if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
529
							$line .= "port {$srcport[0]} ";
530
						} else {
531
							$line .= "port {$srcport[0]}:{$srcport[1]} ";
532 061f78b1 Bill Marquette
						}
533
					}
534
				}
535 0f0c6a9e Scott Ullrich
			}
536 061f78b1 Bill Marquette
537 0f0c6a9e Scott Ullrich
			/* destination address */
538
			if (isset($rule['destination']['any'])) {
539
				$dst = "any";
540
			} else if ($rule['destination']['network']) {
541 03101b55 Scott Ullrich
				if (stristr($rule['destination']['network'], "opt") == true) {
542 0f0c6a9e Scott Ullrich
					$dst = $optcfg[$rule['destination']['network']]['sa'] . "/" .
543 03101b55 Scott Ullrich
						$optcfg[$rule['destination']['network']]['sn'];
544 061f78b1 Bill Marquette
				} else {
545 0f0c6a9e Scott Ullrich
					switch ($rule['destination']['network']) {
546 fa000715 Scott Ullrich
						case 'wanip':
547
							$dst = $wanip;
548
							break;
549
						case 'lanip':
550
							$dst = $lanip;
551
							break;
552 0f0c6a9e Scott Ullrich
						case 'lan':
553 03101b55 Scott Ullrich
							$dst = "$lansa/$lansn";
554
							break;
555 0f0c6a9e Scott Ullrich
						case 'pptp':
556 03101b55 Scott Ullrich
							$dst = "$pptpsa/$pptpsn";
557
							break;
558 0f0c6a9e Scott Ullrich
						case 'pppoe':
559 03101b55 Scott Ullrich
							$dst = "$pppoesa/$pppoesn";
560
							break;
561 061f78b1 Bill Marquette
					}
562
				}
563 0f0c6a9e Scott Ullrich
			} else if ($rule['destination']['address']) {
564
				$dst = alias_expand($rule['destination']['address']);
565
				if(!$dst)
566
					$dst = $rule['destination']['address'];
567
			}
568 061f78b1 Bill Marquette
569 0f0c6a9e Scott Ullrich
			if (!$dst) {
570 03101b55 Scott Ullrich
				printf("No destination address found in rule {$i}. \n");
571
				print_r($rule['destination']['network']);
572 0f0c6a9e Scott Ullrich
				break;
573
			}
574 061f78b1 Bill Marquette
575 0f0c6a9e Scott Ullrich
			if (isset($rule['destination']['not'])) {
576 0a33f73e Scott Ullrich
577
				/*pf is not really happy with this sexy ($dst = "!{$dst}";) approach of
578 2f038c0b Scott Ullrich
				 * negating a list or macro. So we have to write out a ! on each entry.
579 0a33f73e Scott Ullrich
				 */
580 2f038c0b Scott Ullrich
581 0a33f73e Scott Ullrich
				/* not very happy with this! but it beats copying this section to
582 2f038c0b Scott Ullrich
				 * several places.
583
				 */
584
				$alias = alias_expand(substr($dst, 1));
585 0a33f73e Scott Ullrich
586 2f038c0b Scott Ullrich
				if(isset($alias) && stristr($alias, "$")) {
587
					$alias = alias_expand_value(substr($dst, 1));
588
					$dst = "{";
589
					foreach(preg_split("/[\s]+/", $alias) as $item) {
590
						if($item != "") {
591
							$dst .= " !{$item}";
592
						}
593
					}
594
					$dst .= " }";
595
				}
596
				else {
597
					$dst = "!{$dst}";
598
				}
599 0f0c6a9e Scott Ullrich
			}
600 0a33f73e Scott Ullrich
			$line .= " to {$dst} ";
601 0f0c6a9e Scott Ullrich
602
			if (!isset($rule['protocol']) || in_array($rule['protocol'], array("tcp","udp"))) {
603
				if ($rule['destination']['port']) {
604
					$dstport = alias_expand($rule['destination']['port']);
605
					/*
606
					* Check to see if port is a alias.  If so grab it and
607
					* enclose it in { } to pass to pf.
608
					*
609
					* Otherwise combine the portrange into one if its only
610
					* one item.
611
					*/
612
					if($dstport <> "") {
613
						$line .= "port {$dstport}";
614 061f78b1 Bill Marquette
					} else {
615 0f0c6a9e Scott Ullrich
						$dstport = explode("-", $rule['destination']['port']);
616
						if ((!$dstport[1]) || ($dstport[0] == $dstport[1])) {
617
							$dstport = $dstport[0];
618
							$line .= "port {$dstport} ";
619 061f78b1 Bill Marquette
						} else {
620 0f0c6a9e Scott Ullrich
							$dstport = "{$dstport[0]}:{$dstport[1]}";
621
							$line .= "port {$dstport} ";
622 061f78b1 Bill Marquette
						}
623
					}
624
				}
625 0f0c6a9e Scott Ullrich
			}
626 061f78b1 Bill Marquette
627 0f0c6a9e Scott Ullrich
			if ($rule['iptos'])
628 03101b55 Scott Ullrich
				$line .= "tos {$rule['iptos']} ";
629 061f78b1 Bill Marquette
630 0f0c6a9e Scott Ullrich
			$inflags = explode(",", $rule['tcpflags']);
631
			$flags = " flags ";
632
			foreach ($tcpflags as $tcpflag) {
633
				if (array_search($tcpflag, $inflags) !== false) {
634
					$flags .= strtoupper(substr($tcpflag, 0, 1));
635 061f78b1 Bill Marquette
				}
636
			}
637 0f0c6a9e Scott Ullrich
			if($flags <> " flags ")
638
			$line .= "{$flags}/SAFRPU ";
639
640
			$qtag = "{$direction}queue";
641
			$line .= " keep state tagged unshaped tag {$rule[$qtag]} ";
642
643
			$line .= "\n";
644
			$shaperrules .= $line;
645 0a33f73e Scott Ullrich
646 0f0c6a9e Scott Ullrich
			/* setup the outbound queue on the other interface */
647
			$direction = 'out';
648
			$qouttag = "{$direction}queue";
649 0a33f73e Scott Ullrich
650 03101b55 Scott Ullrich
			$friendly_desc = convert_friendly_interface_to_friendly_descr($rule['out-interface']);
651 8ede0d63 Scott Ullrich
			$shaperrules .= "pass out on \${$friendly_desc}";
652 0a33f73e Scott Ullrich
653 0f0c6a9e Scott Ullrich
			if(isset($proto) && $proto != "") {
654
				$shaperrules .= " proto {$proto}";
655
			}
656
			$shaperrules .= " from any to {$dst}";
657
			if(isset($dstport) && $dstport != "") {
658
				$shaperrules .= " port {$dstport}";
659
			}
660
			if ($rule['iptos']) {
661
				$shaperrules .= " tos {$rule['iptos']}";
662
			}
663
			if($flags <> " flags ") {
664
				$shaperrules .= "{$flags}/SAFRPU";
665
			}
666 0a33f73e Scott Ullrich
667 0f0c6a9e Scott Ullrich
			$shaperrules .= " keep state tagged {$rule[$qtag]} tag {$rule[$qouttag]}\n";
668 0a33f73e Scott Ullrich
669 0f0c6a9e Scott Ullrich
			unset($src);
670
			unset($dst);
671
			unset($srcport);
672
			unset($dstport);
673 061f78b1 Bill Marquette
		}
674
675
		$i++;
676
	}
677
	return $shaperrules;
678
}
679
680 191ed731 Scott Ullrich
?>