Project

General

Profile

Download (110 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
		Copyright (C) 2008 Ermal Lu?i
4
		All rights reserved.
5

    
6
		Redistribution and use in source and binary forms, with or without
7
		modification, are permitted provided that the following conditions are met:
8

    
9
		1. Redistributions of source code must retain the above copyright notice,
10
		   this list of conditions and the following disclaimer.
11

    
12
		2. Redistributions in binary form must reproduce the above copyright
13
		   notice, this list of conditions and the following disclaimer in the
14
		   documentation and/or other materials provided with the distribution.
15

    
16
		THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17
		INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18
		AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19
		AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20
		OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
		SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
		INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
		CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
		ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
		POSSIBILITY OF SUCH DAMAGE.
26
*/
27

    
28
/* include all configuration functions */
29
require_once("functions.inc");
30

    
31
/*
32
 * I admit :) this is derived from xmplparse.inc StartElement()
33
 */
34
function &get_reference_to_me_in_config(&$mypath) 
35
{
36
	global $config;
37

    
38
		 $ptr =& $config['shaper'];
39
	foreach ($mypath as $indeks) {
40
				$ptr =& $ptr['queue'][$indeks];
41
		}
42

    
43
	return $ptr;
44
}
45

    
46
function unset_object_by_reference(&$mypath) 
47
{
48
	global $config;
49

    
50
		$ptr =& $config['shaper'];
51
		for ($i = 0; $i < count($mypath) - 1; $i++) {
52
				$ptr =& $ptr['queue'][$mypath[$i]];
53
		}
54
	unset($ptr['queue'][$mypath[$i]]);
55
}
56

    
57
function &get_dn_reference_to_me_in_config(&$mypath) 
58
{
59
	global $config;
60

    
61
		 $ptr =& $config['dnshaper'];
62
	foreach ($mypath as $indeks) {
63
				$ptr =& $ptr['queue'][$indeks];
64
		}
65

    
66
	return $ptr;
67
}
68

    
69
function unset_dn_object_by_reference(&$mypath) 
70
{
71
	global $config;
72

    
73
		$ptr =& $config['dnshaper'];
74
		for ($i = 0; $i < count($mypath) - 1; $i++) {
75
				$ptr =& $ptr['queue'][$mypath[$i]];
76
		}
77
	unset($ptr['queue'][$mypath[$i]]);
78
}
79

    
80
function clean_child_queues($type, $mypath) 
81
{
82
	$ref = &get_reference_to_me_in_config($mypath);
83

    
84
	switch ($type) {
85
	case 'HFSC':
86
		if (isset($ref['borrow'])) unset($ref['borrow']);		
87
		if (isset($ref['hogs'])) unset($ref['hogs']);
88
		if (isset($ref['buckets'])) unset($ref['buckets']);
89
		break;
90
	case 'PRIQ':
91
		if (isset($ref['borrow'])) unset($ref['borrow']);		
92
		if (isset($ref['bandwidth'])) unset($ref['bandwidth']);
93
		if (isset($ref['bandwidthtype'])) unset($ref['bandwidthtype']);
94
		/* fall through */
95
	case 'FAIRQ':
96
		if (isset($ref['borrow'])) unset($ref['borrow']);		
97
		/* fall through */
98
	case 'CBQ':
99
		if (isset($ref['realtime'])) unset($ref['realtime']);	
100
		if (isset($ref['realtime1'])) unset($ref['realtime1']);
101
		if (isset($ref['realtime2'])) unset($ref['realtime2']);
102
		if (isset($ref['realtime3'])) unset($ref['realtime3']);
103
		if (isset($ref['upperlimit'])) unset($ref['upperlimit']);
104
		if (isset($ref['upperlimit1'])) unset($ref['upperlimit1']);
105
		if (isset($ref['upperlimit2'])) unset($ref['upperlimit2']);
106
		if (isset($ref['upperlimit3'])) unset($ref['upperlimit3']);
107
		if (isset($ref['linkshare'])) unset($ref['linkshare']);
108
		if (isset($ref['linkshare1'])) unset($ref['linkshare1']);
109
		if (isset($ref['linkshare2'])) unset($ref['linkshare2']);
110
		if (isset($ref['linkshare3'])) unset($ref['linkshare3']);	
111
		if (isset($ref['hogs'])) unset($ref['hogs']);
112
		if (isset($ref['buckets'])) unset($ref['buckets']);
113
		break;
114
	}
115
}
116

    
117
function get_bandwidthtype_scale($type) 
118
{
119
        switch ($type) {
120
        case "Gb":
121
                $factor = 1000 * 1000 * 1000;
122
        break;
123
        case "Mb":
124
                $factor = 1000 * 1000;
125
        break;
126
        case "Kb":
127
                $factor = 1000;
128
        break;
129
        case "b":
130
        default:
131
                $factor = 1;
132
        break;
133
        }
134
        return floatval($factor);
135
}
136

    
137
function get_hfsc_bandwidth($object, $bw) 
138
{
139
	$pattern= "/[0-9]+/";
140
        if (preg_match($pattern, $bw, $match))
141
                $bw_1 = $match[1];
142
        else
143
                return 0;
144
        $pattern= "/(b|Kb|Mb|Gb|%)/";
145
        if (preg_match($pattern, $bw, $match)) {
146
                switch ($match[1]) {
147
                case '%':
148
                        $bw_1 = $bw_1 / 100 * get_interface_bandwidth($object);
149
                        break;
150
                default:
151
                        $bw_1 = $bw_1 * get_bandwidthtype_scale($match[0]);
152
                        break;
153
                }
154
		return floatval($bw_1);
155
        } else
156
                return 0;
157
}
158

    
159
function get_interface_bandwidth($object) 
160
{
161
	global $altq_list_queues;
162

    
163
        $int = $object->GetInterface();
164
        $altq =& $altq_list_queues[$int];
165
        if ($altq) {
166
                $bw_3 = $altq->GetBandwidth();
167
                $bw_3 = $bw_3 *  get_bandwidthtype_scale($altq->GetBwscale());
168
		return floatval($bw_3);
169
        } else return 0;
170
}
171

    
172
/*
173
 * This is duplicated here since we cannot include guiconfig.inc.
174
 * Including it makes all stuff break.
175
 */
176
function shaper_do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) 
177
{
178

    
179
        /* check for bad control characters */
180
        foreach ($postdata as $pn => $pd) {
181
                if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
182
                        $input_errors[] = "The field '" . $pn . "' contains invalid characters.";
183
                }
184
        }
185

    
186
        for ($i = 0; $i < count($reqdfields); $i++) {
187
                if ($postdata[$reqdfields[$i]] == "") {
188
                        $input_errors[] = "The field '" . $reqdfieldsn[$i] . "' is required.";
189
                }
190
        }
191
}
192

    
193
function cleanup_queue_from_rules($queue) 
194
{
195
	global $config;
196

    
197
	foreach ($config['filter']['rule'] as $rule) {
198
		if ($rule['defaultqueue'] == $queue)
199
			unset($rule['defaultqueue']);
200
		if ($rule['ackqueue'] == $queue)
201
			unset($rule['ackqueue']);
202
	}
203
	foreach ($config['interfaces'] as $if => $ifdata) {
204
			if ($ifdata['ftpqueue'] == $queue) {
205
				unset($config['interfaces'][$if]['ftpqueue']);
206
				break;
207
			}
208
	}
209
}
210

    
211
function cleanup_dnqueue_from_rules($queue) 
212
{
213
	global $config;
214

    
215
	foreach ($config['filter']['rule'] as $rule) {
216
		if ($rule['dnpipe'] == $queue)
217
			unset($rule['dnpipe']);
218
		if ($rule['pdnpipe'] == $queue)
219
			unset($rule['pdnpipe']);
220
	}
221
}
222

    
223
class altq_root_queue {
224
		var $interface;
225
		var $tbrconfig ;
226
		var $bandwidth;
227
		var $bandwidthtype; /* b, Kb, Mb */
228
		var $scheduler;
229
		var $qlimit;
230
		var $queues = array();
231
		var $qenabled;
232
		var $link;
233
		var $default_present; /* if we have a default queue set */
234
		var $available_bw; /* in b/s */
235

    
236
		/* Accesor functions */
237
	function GetAvailableBandwidth() {
238
		return $this->available_bw;
239
	}
240
	function SetAvailableBandwidth($bw) {
241
		$this->available_bw = $bw;
242
	}
243
	function SetDefaultQueuePresent($value) {
244
		$this->default_present = $value;
245
	}
246
	function GetDefaultQueuePresent() {
247
		return trim($this->default_present);
248
	}
249
	function SetLink($link) {
250
		$this->link = $link;
251
	}
252
	function GetLink() {
253
		return $this->link;
254
	}	
255
	function GetEnabled() {
256
		return $this->qenabled;
257
	}
258
	function SetEnabled($value) {
259
		$this->qenabled = $value;
260
	}
261
	function CanHaveChilds() {
262
		return true;
263
	}
264
	function CanBeDeleted() {
265
		return false;
266
	}
267
	function GetQname() {
268
		return $this->interface;
269
	}
270
	function SetQname($name) {
271
		$this->interface = trim($name);
272
	}
273
	function GetInterface() {
274
			return $this->interface;
275
	}
276
	function SetInterface($name) {
277
			$this->interface = trim($name);
278
	}
279
	function GetTbrConfig() {
280
			return $this->tbrconfig;
281
	}
282
	function SetTbrConfig($tbrconfig) {
283
			$this->tbrconfig = $tbrconfig;
284
	}
285
	function GetBandwidth() {
286
			return $this->bandwidth;
287
	}
288
	function SetBandwidth($bw) {
289
			$this->bandwidth = $bw;
290
	}
291
	function GetBwscale() {
292
			return $this->bandwidthtype;
293
	}
294
	function SetBwscale($bwscale) {
295
			$this->bandwidthtype = $bwscale;
296
	}
297
	function GetScheduler() {
298
			return $this->scheduler;
299
	}
300
	function SetScheduler($scheduler) {
301
			$this->scheduler = trim($scheduler);
302
	}
303
	function GetQlimit() {
304
		return $this->qlimit;
305
	}
306
	function SetQlimit($limit) {
307
		$this->qlimit = $limit;
308
	}
309
	
310
	function validate_input($data, &$input_errors) {
311
		
312
		$reqfields[] = "bandwidth";
313
		$reqdfieldsn[] = "Bandwidth";
314
		$reqfields[] = "bandwidthtype";
315
		$reqdfieldsn[] = "Bandwidthtype";
316
		
317
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
318
		
319
                if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
320
                                                $input_errors[] = "Bandwidth must be an integer.";
321
                if ($data['bandwidth'] < 0)
322
                                                $input_errors[] = "Bandwidth cannot be negative.";
323
                if ($data['qlimit'] && (!is_numeric($data['qlimit'])))
324
                                                $input_errors[] = "Qlimit must be an integer.";
325
	 	if ($data['qlimit'] < 0)
326
                                                $input_errors[] = "Qlimit must be an positive.";
327
                if ($data['tbrconfig'] && (!is_numeric($data['tbrconfig'])))
328
                                                $input_errors[] = "Tbrsize must be an integer.";
329
                if ($data['tbrconfig'] < 0)
330
                                                $input_errors[] = "Tbrsize must be an positive.";
331
	}
332

    
333

    
334
	/* Implement this to shorten some code on the frontend page */
335
		function ReadConfig(&$conf) {
336
			if (isset($conf['tbrconfig']))
337
				$this->SetTbrConfig($conf['tbrconfig']);
338
			if ($conf['bandwidth'] <> "") {
339
				$this->SetBandwidth($conf['bandwidth']);
340
				if ($conf['bandwidthtype'] <> "")
341
					$this->SetBwscale($conf['bandwidthtype']);
342
			}
343
		if (isset($conf['scheduler'])) {
344
				if ($this->GetScheduler() != $conf['scheduler']) {
345
					foreach ($this->queues as $q) {
346
						clean_child_queues($conf['scheduler'], $this->GetLink());
347
						$q->clean_queue($conf['scheduler']);
348
					}
349
				}
350
				$this->SetScheduler($conf['scheduler']);
351
			}
352
		if (isset($conf['qlimit']) && $conf['qlimit'] <> "")
353
			$this->SetQlimit($conf['qlimit']);
354
		if (isset($conf['name']))
355
			$this->SetQname($conf['name']);		
356
		$this->SetEnabled($conf['enabled']);
357

    
358
	}
359
	
360
	function copy_queue($interface, &$cflink) {
361
                $cflink['interface'] = $interface;
362
                $cflink['name'] = $interface;
363
                $cflink['scheduler'] = $this->GetScheduler();
364
                $cflink['bandwidth'] = $this->GetBandwidth();
365
                $cflink['bandwidthtype'] = $this->GetBwscale();
366
                $cflink['qlimit'] = $this->GetQlimit();
367
                $cflink['tbrconfig'] = $this->GetTbrConfig();
368
                $cflink['enabled'] = $this->GetEnabled();
369
		if (is_array($this->queues)) {
370
			$cflink['queue'] = array();
371
			foreach ($this->queues as $q) {
372
				$cflink['queue'][$q->GetQname()] = array();
373
				$q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
374
			}
375
		}
376
	}
377

    
378

    
379
		function &get_queue_list($q = null) {
380
			$qlist = array();
381
			
382
			$qlist[$this->GetQname()] = & $this;
383
			if (is_array($this->queues)) {
384
				foreach ($this->queues as $queue)
385
					$queue->get_queue_list(&$qlist);
386
			}
387
			return $qlist;
388
		}
389

    
390
		function &add_queue($interface, &$queue, &$path, &$input_errors) {
391

    
392
			if (!is_array($this->queues))
393
				$this->queues = array();
394
				
395
			switch ($this->GetScheduler()) {
396
				case "PRIQ":
397
					$q =& new priq_queue();
398
					break;
399
				case "HFSC":
400
					$q =& new hfsc_queue();
401
					break;
402
				case "CBQ":
403
					$q =& new cbq_queue();
404
					break;
405
				case "FAIRQ":
406
					$q =& new fairq_queue();
407
					break;
408
				default:
409
					/* XXX: but should not happen anyway */ 
410
					return;
411
					break;
412
			}
413
			$q->SetLink($path);
414
			$q->SetInterface($this->GetInterface());
415
			$q->SetEnabled("on");
416
			$q->SetParent(&$this);
417
			$q->ReadConfig($queue);
418
			$q->validate_input($queue, $input_errors);
419
                 if (count($input_errors)) {
420
                       return $q;
421
                 }
422

    
423
                 if (isset($queue['bandwidth'])) {
424
                         switch ($queue['bandwidthtype']) {
425
                         case "%":
426
                                $myBw = $this->GetAvailableBandwidth() * $queue['bandwidth'] / 100;
427
                                break;
428
                        default:
429
                                $myBw = $queue['bandwidth'] * get_bandwidthtype_scale($queue['bandwdithtype']);
430
                                break;
431
                        }
432
                 	}
433
			$q->SetAvailableBandwidth($myBw);
434
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
435
			$this->queues[$q->GetQname()] = &$q; 
436
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
437
			if (is_array($queue['queue'])) {
438
				foreach ($queue['queue'] as $key1 => $que) {
439
					array_push($path, $key1);
440
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
441
					array_pop($path);
442
						}
443
			}
444
	
445
			return $q;
446
		}
447

    
448
		/* interface here might be optional */
449
		function &find_queue($interface, $qname) {
450
			if ($qname == $this->GetQname()) {
451
				return $this;
452
			} 
453
			foreach ($this->queues as $q) {
454
				$result =& $q->find_queue("", $qname);
455
				if ($result)
456
					return $result;
457
			}
458
		}
459

    
460
	function &find_parentqueue($interface, $qname) {
461
		if ($qname == $interface) {
462
			$result =  NULL;
463
		} else if ($this->queues[$qname])	 {
464
			$result = $this;
465
		} else if ($this->GetScheduler() <> "PRIQ") {
466
			foreach ($this->queues as $q) {
467
				$result = $q->find_parentqueue("", $qname);
468
				if ($result)
469
					return $result;
470
			}
471
		}
472
	}
473

    
474
	function build_tree() {
475
		global $shaperIFlist;
476

    
477
		$tree = " <li><a href=\"firewall_shaper.php?interface=".$this->GetInterface()."&queue=". $this->GetInterface()."&action=show"; 
478
		$tree .= "\">" . $shaperIFlist[$this->GetInterface()] . "</a>";
479
		if (is_array($this->queues)) {
480
			$tree .= "<ul>";
481
			foreach ($this->queues as $q)  {
482
				$tree .= $q->build_tree();
483
			}
484
		$tree .= "</ul>";
485
		}
486
		$tree .= "</li>";
487
		return $tree;
488
	}
489
	
490
	function delete_queue() { 
491
		foreach ($this->queues as $q) {
492
		$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
493
			$q->delete_queue();			
494
		}
495
		unset_object_by_reference($this->GetLink());
496
	 }
497

    
498
	function delete_all() {
499
                if (count($this->queues)) {
500
                        foreach ($this->queues as $q) {
501
                        	$q->delete_all();
502
                        	unset_object_by_reference($q->GetLink());
503
                                unset($q);
504
               		}
505
        	        unset($this->queues);
506
                }
507
        }
508

    
509
	/*
510
	 * First it spits:
511
	 * altq on $interface ..............
512
	 *      then it goes like
513
	 *      foreach ($queues as $qkey => $queue)
514
	 *              this->queues[$qkey]->build_rule();
515
	 */
516
	function build_rules() {
517
		if (count($this->queues) > 0 && $this->GetEnabled()) {
518
			$rules = " altq on  " . get_real_interface($this->GetInterface());
519
			if ($this->GetScheduler())
520
					$rules .= " ".strtolower($this->GetScheduler());
521
			if ($this->GetBandwidth())
522
					$rules .= " bandwidth ".trim($this->GetBandwidth());
523
			if ($this->GetBwscale())
524
					$rules .= $this->GetBwscale();
525
			if ($this->GetTbrConfig())
526
					$rules .= " tbrsize ".$this->GetTbrConfig();
527
			if (count($this->queues)) {
528
					$i = count($this->queues);
529
					$rules .= " queue { ";
530
					foreach ($this->queues as $qkey => $qnone) {
531
							if ($i > 1) {
532
									$i--;
533
									$rules .= " {$qkey}, ";
534
							} else
535
									$rules .= " {$qkey} ";
536
					}
537
					$rules .= " } \n";
538
					foreach ($this->queues as $q) {
539
							$rules .= $q->build_rules();
540
					}
541
			}
542
		}
543
		$rules .= " \n";
544
		return $rules;
545
	}
546

    
547
	function build_javascript() {
548
			$javascript = "<script type=\"text/javascript\">";
549
			$javascript .= "function mySuspend() {";
550
			$javascript .= "if (document.layers && document.layers['shaperarea'] != null);";
551
			$javascript .= "document.layers['shaperarea'].visibility = 'hidden';";
552
			$javascript .= "else if (document.all)";
553
			$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';";
554
			$javascript .= "}";
555

    
556
			$javascript .= "function myResume() {";
557
			$javascript .= "if (document.layers && document.layers['shaperarea'] != null)";
558
			$javascript .= "document.layers['shaperarea'].visibility = 'visible';";
559
			$javascript .= "else if (document.all)";
560
			$javascript .= "document.all['shaperarea'].style.visibility = 'visible';";
561
			$javascript .= "}";
562
			$javascript .= "</script>";
563

    
564
			return $javascript;
565
	}
566
	
567
	function build_shortform() {
568
			global $g;
569

    
570
			$altq =& $this;
571
			if ($altq)
572
					$scheduler = ": " . $altq->GetScheduler();
573
			$form = "<tr><td width=\"20%\" class=\"vtable\">";
574
			$form .= "<a href=\"firewall_shaper.php?interface" . $this->GetInterface() . "&queue=". $this->GetInterface()."&action=show\">".$this->GetInterface().": ".$scheduler."</a>";
575
			$form .= "</td></tr>";
576
			$form .= "<tr>";
577
			$form .= "<td width=\"50%\" class=\"vncellreq\">";
578
			$form .= "Bandwidth: " . $this->GetBandwidth().$this->GetBwscale();
579
			$form .= "</td><td width=\"50%\"></td></tr>";
580
			$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
581
			$form .= "<a href=\"firewall_shaper_queues.php?interface=";
582
			$form .= $this->GetInterface() . "&queue=";
583
			$form .= $this->GetQname() . "&action=delete\">";
584
			$form .= "<img src=\"";
585
			$form .= "./themes/".$g['theme']."/images/icons/icon_x.gif\"";
586
			$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Disable shaper on i
587
nterface\">";
588
			$form .= "<span>Disable shaper on interface</span></a></td></tr>";
589

    
590
			return $form;
591

    
592
	}
593
		/*
594
		 * For requesting the parameters of the root queue
595
		 * to the user like the traffic wizard does.
596
		 */
597
	function build_form() { 
598
		$form = "<tr><td valign=\"top\" class=\"vncellreq\"><br><span class=\"vexpl\">Name</span></td>";
599
		$form .= "<td class=\"vncellreq\">";
600
		$form .= "<strong>".$this->GetQname()."</strong>";
601
		$form .= "</td></tr>";
602
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Scheduler Type ";
603
		$form .= "</td>";
604
		$form .= "<td class=\"vncellreq\">";
605
		$form .= "<select id=\"scheduler\" name=\"scheduler\" class=\"formselect\">";
606
		$form .= "<option value=\"HFSC\"";
607
		if ($this->GetScheduler() == "HFSC")
608
			$form .= " selected=\"yes\"";
609
		$form .= ">HFSC</option>";
610
		$form .= "<option value=\"CBQ\"";
611
		if ($this->GetScheduler() == "CBQ")
612
			$form .= " selected=\"yes\"";
613
		$form .= ">CBQ</option>";
614
		$form .= "<option value=\"FAIRQ\"";
615
                if ($this->GetScheduler() == "FAIRQ")
616
                	$form .= " selected=\"yes\"";
617
                $form .= ">FAIRQ</option>";
618
		$form .= "<option value=\"PRIQ\"";
619
		if ($this->GetScheduler() == "PRIQ")
620
			$form .= " selected=\"yes\"";
621
		$form .= ">PRIQ</option>";
622
		$form .= "</select>";
623
		$form .= "<br> <span class=\"vexpl\">";
624
		$form .= "NOTE: changing this changes all queues underneath!";
625
		$form .= " Beaware you can lose information.";
626
		$form .= "</span>";
627
		$form .= "</td></tr>";
628
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Bandwidth";
629
		$form .= "</td><td class=\"vncellreq\">";
630
		$form .= "<input type=\"text\" id=\"bandwidth\" name=\"bandwidth\" value=\"";
631
		$form .= $this->GetBandwidth() . "\">"; 
632
		$form .= "<select id=\"bandwidthtype\" name=\"bandwidthtype\" class=\"formselect\">";
633
		$form .= "<option value=\"Kb\"";
634
		if ($this->GetBwscale() == "Kb")
635
			$form .= " selected=\"yes\"";
636
		$form .= ">Kbit/s</option>";
637
		$form .= "<option value=\"Mb\"";
638
		if ($this->GetBwscale() == "Mb")
639
			$form .= " selected=\"yes\"";
640
		$form .= ">Mbit/s</option>";
641
		$form .= "<option value=\"Gb\"";
642
		if ($this->GetBwscale() == "Gb")
643
			$form .= " selected=\"yes\"";
644
		$form .= ">Gbit/s</option>";		
645
		$form .= "<option value=\"\"";
646
		if ($this->GetBwscale() == "b")
647
			$form .= " selected=\"yes\"";
648
		$form .= ">Bit/s</option>";
649
		$form .= "</select>";
650
		$form .= "</td></tr>";
651
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Queue Limit</td>";
652
		$form .= "<td class=\"vncellreq\">";
653
		$form .= "<input type=\"text\" id=\"qlimit\" name=\"qlimit\" value=\"";
654
		$form .= $this->GetQlimit();
655
		$form .= "\">";
656
		$form .= "</td></tr>";
657
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Tbr Size</td>";
658
		$form .= "<td class=\"vncellreq\">";
659
		$form .= "<input type=\"text\" id=\"tbrconfig\" name=\"tbrconfig\" value=\"";
660
		$form .= $this->GetTbrConfig();
661
		$form .= "\">";
662
		$form .= "<br> <span class=\"vexpl\">";
663
		$form .= "Adjusts the size, in bytes, of the token bucket regulator.";
664
		$form .= "If not specified, heuristics based on the interface ";
665
		$form .= "bandwidth are used to determine the size.";
666
				$form .= "</span></td></tr>";
667
		$form .= "<input type=\"hidden\" id=\"interface\" name=\"interface\"";
668
		$form .= " value=\"" . $this->GetInterface() . "\">";
669
		$form .= "<input type=\"hidden\" id=\"name\" name=\"name\" value=\"".$this->GetQname()."\" >";
670

    
671

    
672
		return $form;
673
	}
674

    
675
		function update_altq_queue_data(&$data) { 
676
		$this->ReadConfig($data);
677
	}
678
	
679
	/*
680
	 * Should call on each of it queues and subqueues
681
	 * the same function much like build_rules();
682
	 */
683
	function wconfig() { 
684
		$cflink = &get_reference_to_me_in_config($this->GetLink());
685
		if (!is_array($cflink))
686
			$cflink = array();
687
		$cflink['interface'] = $this->GetInterface();	
688
		$cflink['name'] = $this->GetQname();
689
		$cflink['scheduler'] = $this->GetScheduler();
690
		$cflink['bandwidth'] = $this->GetBandwidth();
691
		$cflink['bandwidthtype'] = $this->GetBwscale();
692
		$cflink['qlimit'] = $this->GetQlimit();
693
		$cflink['tbrconfig'] = $this->GetTbrConfig();
694
		$cflink['enabled'] = $this->GetEnabled();
695
	}
696

    
697
}
698

    
699
class priq_queue {
700
	var $qname;
701
	var $qinterface; 
702
	var $qlimit;
703
	var $qpriority;
704
	var $description;
705
	var $isparent;
706
	var $qbandwidth;
707
	var $qbandwidthtype;
708
	var $qdefault;
709
	var $qrio;
710
	var $qred;
711
	var $qecn;
712
	var $qack;
713
	var $qenabled;
714
	var $qparent;
715
	var $link;
716
	var $available_bw; /* in b/s */
717

    
718
	/* This is here to help on form building and building rules/lists */
719
		var $subqueues = array();
720

    
721
	/* Accesor functions */
722
	function GetAvailableBandwidth() {
723
		return $this->available_bw;
724
	}
725
	function SetAvailableBandwidth($bw) {
726
		$this->available_bw = $bw;
727
	}
728
	function SetLink($link) {
729
			$this->link = $link;
730
	}
731
	function GetLink() {
732
			return $this->link;
733
	}
734
	function &GetParent() {
735
		return $this->qparent;
736
	}
737
	function SetParent(&$parent) {
738
		$this->qparent = &$parent;
739
	}
740
	function GetEnabled() {
741
			return $this->qenabled;
742
	}
743
	function SetEnabled($value) {
744
			$this->qenabled = $value;
745
	}
746
	function CanHaveChilds() {
747
			return false;
748
	}
749
	function CanBeDeleted() {
750
			return true;
751
	}
752
	function GetQname() {
753
			return $this->qname;
754
	}
755
	function SetQname($name) {
756
			$this->qname = trim($name);
757
	}
758
	function GetBandwidth() {
759
			return $this->qbandwidth;
760
	}
761
	function SetBandwidth($bandwidth) {
762
			$this->qbandwidth = $bandwidth;
763
	}
764
	function GetInterface() {
765
			return $this->qinterface;
766
	}
767
	function SetInterface($name) {
768
			$this->qinterface = trim($name);
769
	}
770
	function GetQlimit() {
771
			return $this->qlimit;
772
	}
773
	function SetQlimit($limit) {
774
			$this->qlimit = $limit;
775
	}
776
	function GetQpriority() {
777
			return $this->qpriority;
778
	}
779
	function SetQpriority($priority) {
780
			$this->qpriority = $priority;
781
	}
782
	function GetDescription() {
783
			return $this->description;
784
	}
785
	function SetDescription($str) {
786
			$this->description = trim($str);
787
	}
788
	function GetFirstime() {
789
			return $this->firsttime;
790
	}
791
	function SetFirsttime($number) {
792
			$this->firsttime = $number;
793
	}
794
	function GetBwscale() {
795
			return $this->qbandwidthtype;
796
	}
797
	function SetBwscale($scale) {
798
			$this->qbandwidthtype = $scale;
799
	}
800
	function GetDefault() {
801
			return $this->qdefault;
802
	}
803
	function SetDefault($value = false) {
804
			$this->qdefault = $value;
805
	altq_set_default_queue($this->GetInterface(), "true");
806
	}
807
	function GetRed() {
808
			return $this->qred;
809
	}
810
	function SetRed($red = false) {
811
			$this->qred = $red;
812
	}
813
	function GetRio() {
814
			return $this->qrio;
815
	}
816
	function SetRio($rio = false) {
817
			$this->qrio = $rio;
818
	}
819
function GetEcn() {
820
			return $this->qecn;
821
	}
822
	function SetEcn($ecn = false) {
823
			$this->qecn = $ecn;
824
	}
825
	function GetAck() {
826
			return $this->qack;
827
	}
828
	function SetAck($ack = false) {
829
			$this->qack = $ack;
830
	}
831

    
832
	function build_javascript() {
833
		$javascript = "<script type=\"text/javascript\">";
834
		$javascript .= "function mySuspend() { \n";
835
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null);\n";
836
		$javascript .= "document.layers['shaperarea'].visibility = 'hidden';\n";
837
		$javascript .= "else if (document.all)\n";
838
		$javascript .= "document.all['shaperarea'].style.visibility = 'hidden';\n";
839
		$javascript .= "}\n";
840

    
841
		$javascript .= "function myResume() {\n";
842
		$javascript .= "if (document.layers && document.layers['shaperarea'] != null)\n";
843
		$javascript .= "document.layers['shaperarea'].visibility = 'visible';\n";
844
		$javascript .= "else if (document.all)\n";
845
		$javascript .= "document.all['shaperarea'].style.visibility = 'visible';\n";
846
		$javascript .= "}\n";
847
		$javascript .= "</script>";
848
		
849
		return $javascript;
850
	}
851
	
852
	function &add_queue($interface, &$qname, &$path, &$input_errors) { return; }
853

    
854
	/* 
855
	 * Currently this will not be called unless we decide to clonce whole 
856
	 * queue tree on the 'By Queues' view or support drag&drop on the tree/list
857
	 */
858
	 function copy_queue($interface, &$cflink) {
859

    
860
 		$cflink['name'] = $this->GetQname();
861
                $cflink['interface'] = $interface;
862
                $cflink['qlimit'] = $this->GetQlimit();
863
                $cflink['priority'] = $this->GetQpriority();
864
                $cflink['description'] = $this->GetDescription();
865
                $cflink['enabled'] = $this->GetEnabled();
866
                $cflink['default'] = $this->GetDefault();
867
                $cflink['red'] = $this->GetRed();
868
                $cflink['rio'] = $this->GetRio();
869
                $cflink['ecn'] = $this->GetEcn();
870

    
871
                if (is_array($this->subqueues)) {
872
                        $cflinkp['queue'] = array();
873
                        foreach ($this->subqueues as $q) {
874
				 $cflink['queue'][$q->GetQname()] = array();
875
                                $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
876
			}
877
                }
878

    
879
	 }
880

    
881
	function clean_queue($sched) {
882
		clean_child_queues($sched, $this->GetLink());
883
		if (is_array($this->subqueues)) {
884
				foreach ($this->subqueues as $q)
885
						$q->clean_queue($sched);
886
				}
887
		}
888

    
889

    
890
		
891
        function &get_queue_list(&$qlist) {
892
                        $qlist[$this->GetQname()] = & $this;
893
                        if (is_array($this->subqueues)) {
894
                                foreach ($this->subqueues as $queue)
895
                                        $queue->get_queue_list($qlist);
896
                        }
897
        }
898

    
899
	function delete_queue() {
900
		unref_on_altq_queue_list($this->GetQname());
901
		if ($this->GetDefault())
902
				altq_set_default_queue($this->GetInterface(), "false");
903
		cleanup_queue_from_rules($this->GetQname());
904
		unset_object_by_reference($this->GetLink());
905
	}
906
	
907
	function delete_all() {
908
                if (count($this->subqueues)) {
909
                        foreach ($this->subqueues as $q) {
910
                                $q->delete_all();
911
                                unset_object_by_reference($q->GetLink());
912
                                unset($q);
913
                        }
914
                        unset($this->subqueues);
915
                }
916
        }
917

    
918
	 function &find_queue($interface, $qname) { 
919
		if ($qname == $this->GetQname())
920
			return $this; 
921
	}
922
	
923
	function find_parentqueue($interface, $qname) { return; }
924
		
925
	function validate_input($data, &$input_errors) {
926
	
927
		$reqfields[] = "name";
928
		$erqfieldsn[] = "Name";
929
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
930

    
931
		if ($data['priority'] && (!is_numeric($data['priority'])
932
						|| ($data['priority'] < 1) || ($data['priority'] > 15))) {
933
					$input_errors[] = "The priority must be an integer between 1 and 15.";
934
		}
935
		if ($data['qlimit'] && (!is_numeric($data['qlimit']))) 
936
				$input_errors[] = "Queue limit must be an integer";
937
		if ($data['qlimit'] < 0)
938
				$input_errors[] = "Queue limit must be positive";
939
		if (!preg_match("/^[a-zA-Z0-9_-]*$/", $data['name']))
940
			 $input_errors[] = "Queue names must be alphanumeric and _ or - only.";
941
		
942
	}
943

    
944
	function ReadConfig(&$q) {
945
		if (isset($q['name']))
946
				$this->SetQname($q['name']);
947
		if (isset($q['interface']))
948
				$this->SetInterface($q['interface']);
949
		if ($q['bandwidth'] <> "") {
950
			$this->SetBandwidth($q['bandwidth']);
951
			if ($q['bandwidthtype'] <> "")
952
				$this->SetBwscale($q['bandwidthtype']);
953
		}
954
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
955
					$this->SetQlimit($q['qlimit']);
956
				if (isset($q['priority']))
957
						$this->SetQPriority($q['priority']);
958
				if (isset($q['description']) && $q['description'] != "")
959
						$this->SetDescription($q['description']);
960
		if (isset($q['ftpqueue']) && $q['ftpqueue'] <> "") 
961
			set_is_ftp_queue($this->GetInterface(), $this->GetQname());
962
		$this->SetRed($q['red']);
963
		$this->SetRio($q['rio']);
964
		$this->SetEcn($q['ecn']);
965
		$this->SetDefault($q['default']);
966
		$this->SetEnabled($q['enabled']);
967

    
968
		}
969

    
970
	function build_tree() {
971
			$tree = " <li><a href=\"firewall_shaper.php?interface=". $this->GetInterface()."&queue=". $this->GetQname()."&action=show"; 
972
			$tree .= "\" ";
973
			if ($this->GetDefault())
974
				$tree .= " class=\"navlnk\"";
975
			$tree .= " >" . $this->GetQname() . "</a>";
976
			/* 
977
			 * Not needed here!
978
			 * if (is_array($queues) {
979
			 *	  $tree .= "<ul>";
980
			 *	  foreach ($q as $queues) 
981
			 *		  $tree .= $queues['$q->GetName()']->build_tree();
982
			 *	  endforeach	
983
			 *	  $tree .= "</ul>";
984
			 * }
985
			 */
986

    
987
			$tree .= "</li>"; 
988

    
989
			return $tree;
990
		}
991
		
992
		/* Should return something like:
993
		 * queue $qname on $qinterface bandwidth ....
994
		 */
995
		function build_rules() {
996
				$pfq_rule = " queue ". $this->qname;
997
				if ($this->GetInterface())
998
						$pfq_rule .= " on ".get_real_interface($this->GetInterface());
999
				if ($this->GetQpriority())
1000
						$pfq_rule .= " priority ".$this->GetQpriority();
1001
				if ($this->GetQlimit())
1002
						$pfq_rule .= " qlimit " . $this->GetQlimit();
1003
				if ($this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetDefault()) {
1004
						$pfq_rule .= " priq ( ";
1005
					if ($this->GetRed()) {
1006
						$comma = 1;
1007
						$pfq_rule .= " red ";
1008
					}
1009
					if ($this->GetRio()) {
1010
						if ($comma) 
1011
								$pfq_rule .= " ,";
1012
						$comma = 1;
1013
						$pfq_rule .= " rio ";
1014
					}
1015
					if ($this->GetEcn()) {
1016
						if ($comma) 
1017
								$pfq_rule .= " ,";
1018
						$comma = 1;
1019
						$pfq_rule .= " ecn ";
1020
					}	
1021
					if ($this->GetDefault()) {
1022
						if ($comma)
1023
							$pfq_rule .= " ,";
1024
						$pfq_rule .= " default ";
1025
					}
1026
					$pfq_rule .= " ) ";
1027
				}
1028
	
1029
				$pfq_rule .= " \n";
1030
		
1031
				return $pfq_rule;
1032
		}
1033

    
1034
		/*
1035
		 * To return the html form to show to user
1036
		 * for getting the parameters.
1037
		 * Should do even for first time when the
1038
		 * object is created and later when we may
1039
		 * need to update it.
1040
		 */
1041
		function build_form() {
1042
				$form .= "<tr>";
1043
		$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">";
1044
		$form .= "Queue Name</td><td width=\"78%\" class=\"vtable\">";
1045
		$form .= "<input name=\"name\" type=\"text\" id=\"name\" class=\"formfld unknown\" size=\"15\" maxlength=\"15\" value=\"";
1046
		$form .= htmlspecialchars($this->GetQname());
1047
		$form .= "\">";
1048
				$form .= "<br> <span class=\"vexpl\">Enter the name of the queue here.  Do not use spaces and limit the size to 15 characters.";
1049
				$form .= "</span></td>";
1050
		$form .= "</tr><tr>";
1051
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Priority</td>";
1052
				$form .= "<td width=\"78%\" class=\"vtable\"> <input name=\"priority\" type=\"text\" id=\"priority\" size=\"5\" value=\"";
1053
				$form .= htmlspecialchars($this->GetQpriority());
1054
				$form .= "\">";
1055
				$form .= "<br> <span class=\"vexpl\">For hfsc, the range is 0 to 7. The default is 1.  Hfsc queues with a higher priority are preferred in the case of overload.</span></td>";
1056
				$form .= "</tr>";
1057
				$form .= "</tr>";
1058
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Queue limit</td>";
1059
				$form .= "<td width=\"78%\" class=\"vtable\"> <input name=\"qlimit\" type=\"text\" id=\"qlimit\" size=\"5\" value=\"";
1060
				$form .= htmlspecialchars($this->GetQlimit());
1061
				$form .= "\">";
1062
		$form .= "<br> <span class=\"vexpl\">Queue limit in packet per second."; 
1063
				$form .= "</span></td>";
1064
				$form .= "<tr>";
1065
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncell\">Scheduler options</td>";
1066
				$form .= "<td width=\"78%\" class=\"vtable\">";
1067
		if ($this->GetDefault()) { 
1068
				$form .= "<input type=\"checkbox\" id=\"default\" CHECKED name=\"default\"";
1069
		$form .= "> Default queue<br>";
1070
		} else {
1071
			$form .= "<input type=\"checkbox\" id=\"default\" name=\"default\"";
1072
					$form .= "> Default queue<br>";
1073
		}
1074
		/* XXX: TODO Add check to disable this if it has been set on another queue on this interface. */
1075
		$form .= "<input type=\"checkbox\" id=\"ftpqueue\" name=\"ftpqueue\" ";
1076
		if (get_is_ftp_queue($this->GetInterface(), $this->GetQname()))  
1077
			$form .= " CHECKED";
1078
		$form .= ">Use this queue for the ftp proxy<br>";
1079
		/* XXX: TODO */
1080
				$form .= "<input type=\"checkbox\" id=\"red\" name=\"red\"";
1081
				if($this->GetRed()) 
1082
			$form .=  " CHECKED";
1083
		$form .= "> <a target=\"_new\" href=\"http://www.openbsd.org/faq/pf/queueing.html#red\">Random Early Detection</a><br>";
1084
				$form .= "<input type=\"checkbox\" id=\"rio\" name=\"rio\"";
1085
				if($this->GetRio()) 
1086
			$form .=  " CHECKED";
1087
		$form .= "> <a target=\"_new\" href=\"http://www.openbsd.org/faq/pf/queueing.html#rio\">Random Early Detection In and Out</a><br>";
1088
				$form .= "<input type=\"checkbox\" id=\"ecn\" name=\"ecn\"";
1089
				if($this->GetEcn()) 
1090
			$form .=  " CHECKED";
1091
		$form .= "> <a target=\"_new\" href=\"http://www.openbsd.org/faq/pf/queueing.html#ecn\">Explicit Congestion Notification</a><br>";
1092
				$form .= "<span class=\"vexpl\"><br>Select options for this queue";
1093
				$form .= "</tr><tr>";
1094
		$form .= "<td width=\"22%\" class=\"vncellreq\">Description</td>";
1095
		$form .= "<td width=\"78%\" class=\"vtable\">";
1096
		$form .= "<input type=\"text\" name=\"description\" size=\"50%\" class=\"formfld unknown\" value=\"" . $this->GetDescription() . "\"  >";
1097
		$form .= "</td></tr>";
1098
		$form .= "<input type=\"hidden\" name=\"interface\" id=\"interface\"";
1099
				$form .= " value=\"".$this->GetInterface()."\">";
1100

    
1101
		return $form;
1102
		}
1103

    
1104
	function build_shortform() {
1105
		/* XXX: Hacks in site. Mostly layer violations!  */
1106
		global $g, $altq_list_queues;
1107

    
1108
		$altq =& $altq_list_queues[$this->GetInterface()];
1109
		if ($altq)
1110
			$scheduler = ": " . $altq->GetScheduler();
1111
		 $form = "<tr><td width=\"20%\" class=\"vtable\">";
1112
		$form .= "<a href=\"firewall_shaper.php?interface" . $this->GetInterface() . "&queue=" . $this->GetInterface()."&action=show\">".$this->GetInterface().": ".$scheduler."</a>";
1113
		$form .= "</td></tr>";
1114
		/* 
1115
		 * XXX: Hack in sight maybe fix with a class that wraps all
1116
		 * of this layer violations
1117
		 */
1118
		$form .= "<tr>";
1119
		$form .= "<td width=\"50%\" class=\"vncellreq\">";
1120
		$form .= "Bandwidth: " . $this->GetBandwidth().$this->GetBwscale();
1121
		$form .= "</td><td width=\"50%\"></td></tr>";
1122
		$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
1123
		if ($this->GetQpriority())
1124
			$form .= "Priority: on </td></tr>";
1125
		if ($this->GetDefault())
1126
			$form .= "<tr><td class=\"vncellreq\">Default: on </td></tr>";
1127
		$form .= "<tr><td width=\"20%\" class=\"vncellreq\">";
1128
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
1129
			$form .= $this->GetInterface() . "&queue=";
1130
			$form .= $this->GetQname() . "&action=delete\">";
1131
			$form .= "<img src=\"";
1132
			$form .= "./themes/".$g['theme']."/images/icons/icon_x.gif\"";
1133
			$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Delete queue from interface\">";
1134
			$form .= "<span>Delete queue from interface</span></a></td></tr>";
1135
		
1136
		return $form;
1137

    
1138
	}
1139

    
1140
		function update_altq_queue_data(&$q) { 
1141
		$this->ReadConfig($q);
1142
	}
1143

    
1144
		function wconfig() {
1145
			$cflink =& get_reference_to_me_in_config($this->GetLink());
1146
		if (!is_array($cflink))
1147
			$cflink = array();
1148
		$cflink['name'] = $this->GetQname();
1149
				$cflink['interface'] = $this->GetInterface();
1150
				$cflink['qlimit'] = $this->GetQlimit();
1151
				$cflink['priority'] = $this->GetQpriority();
1152
		$cflink['description'] = $this->GetDescription();
1153
		$cflink['enabled'] = $this->GetEnabled();
1154
		$cflink['default'] = $this->GetDefault();
1155
		$cflink['red'] = $this->GetRed();
1156
		$cflink['rio'] = $this->GetRio();
1157
		$cflink['ecn'] = $this->GetEcn();
1158
	}
1159
}
1160

    
1161
class hfsc_queue extends priq_queue {
1162
		/* realtime */
1163
	var $realtime;
1164
		var $r_m1;
1165
		var $r_d;
1166
		var $r_m2;
1167
		/* linkshare */
1168
	var $linkshare;
1169
		var $l_m1;
1170
		var $l_d;
1171
		var $l_m2;
1172
		/* upperlimit */
1173
	var $upperlimit;
1174
		var $u_m1;
1175
		var $u_d;
1176
		var $u_m2;
1177

    
1178
		/*
1179
		 * HFSC can have nested queues.
1180
		 */
1181

    
1182
	function CanHaveChilds() {
1183
				return true;
1184
		}
1185
	function GetRealtime() {
1186
           return $this->realtime;
1187
     }
1188
     function GetR_m1() {
1189
           return $this->r_m1;
1190
     }
1191
     function GetR_d() {
1192
           return $this->r_d;
1193
     }
1194
     function GetR_m2() {
1195
           return $this->r_m2;
1196
     }
1197
     function SetRealtime() {
1198
           $this->realtime = "on";
1199
     }
1200
     function DisableRealtime() {
1201
           $this->realtime = "";
1202
     }
1203
     function SetR_m1($value) {
1204
           $this->r_m1 = $value;
1205
     }
1206
     function SetR_d($value) {
1207
           $this->r_d = $value;
1208
     }
1209
     function SetR_m2($value) {
1210
           $this->r_m2 = $value;
1211
     }
1212
     function GetLinkshare() {
1213
           return $this->linkshare;
1214
     }
1215
     function DisableLinkshare() {
1216
           $this->linkshare = "";
1217
     }
1218
     function GetL_m1() {
1219
           return $this->l_m1;
1220
     }
1221
     function GetL_d() {
1222
           return $this->l_d;
1223
     }
1224
     function GetL_m2() {
1225
           return $this->l_m2;
1226
     }
1227
     function SetLinkshare() {
1228
           $this->linkshare = "on";
1229
     }
1230
     function SetL_m1($value) {
1231
           $this->l_m1 = $value;
1232
     }
1233
     function SetL_d($value) {
1234
           $this->l_d = $value;
1235
     }
1236
     function SetL_m2($value) {
1237
           $this->l_m2 = $value;
1238
     }
1239
     function GetUpperlimit() {
1240
           return $this->upperlimit;
1241
     }
1242
     function GetU_m1() {
1243
           return $this->u_m1;
1244
     }
1245
     function GetU_d() {
1246
           return $this->u_d;
1247
     }
1248
     function GetU_m2() {
1249
           return $this->u_m2;
1250
     }
1251
     function SetUpperlimit() {
1252
           $this->upperlimit = "on";
1253
     }
1254
     function DisableUpperlimit() {
1255
           $this->upperlimit = "";
1256
     }
1257
     function SetU_m1($value) {
1258
           $this->u_m1 = $value;
1259
     }
1260
     function SetU_d($value) {
1261
           $this->u_d = $value;
1262
     }
1263
     function SetU_m2($value) {
1264
           $this->u_m2 = $value;
1265
     }
1266

    
1267

    
1268

    
1269
		function &add_queue($interface, &$qname, &$path, &$input_errors) {
1270

    
1271
			if (!is_array($this->subqueues))
1272
							$this->subqueues = array();
1273
			$q =& new hfsc_queue();
1274
			$q->SetInterface($this->GetInterface());
1275
			$q->SetParent(&$this);
1276
			$q->ReadConfig($qname);
1277
			$q->validate_input($qname, $input_errors);
1278
			if (count($input_errors)) {
1279
				return $q;
1280
			}
1281
			
1282
			$q->SetEnabled("on");
1283
			$q->SetLink($path);
1284
			switch ($q->GetBwscale()) {
1285
                        case "%":
1286
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1287
                                break;
1288
                        default:
1289
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1290
                                break;
1291
                	}
1292
                        $q->SetAvailableBandwidth($myBw);
1293
                        $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1294

    
1295
			$this->subqueues[$q->GetQname()] =& $q; //new hfsc_queue()
1296
			ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1297
			if (is_array($qname['queue'])) {
1298
				foreach ($qname['queue'] as $key1 => $que) {
1299
					array_push($path, $key1);
1300
								$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1301
					array_pop($path);
1302
				}
1303
					}
1304
	
1305
			return $q;
1306
		}
1307

    
1308
 	        function copy_queue($interface, &$cflink) {
1309

    
1310
                        $cflink['name'] = $this->GetQname();
1311
                        $cflink['interface'] = $interface;
1312
                        $cflink['qlimit'] = $this->GetQlimit();
1313
                        $cflink['priority'] = $this->GetQpriority();
1314
                        $cflink['description'] = $this->GetDescription();
1315
                        $cflink['bandwidth'] = $this->GetBandwidth();
1316
                        $cflink['bandwidthtype'] = $this->GetBwscale();
1317
                        $cflink['enabled'] = $this->GetEnabled();
1318
                        $cflink['default'] = $this->GetDefault();
1319
                        $cflink['red'] = $this->GetRed();
1320
                        $cflink['rio'] = $this->GetRio();
1321
                        $cflink['ecn'] = $this->GetEcn();
1322
                        if ($this->GetLinkshare() <> "") {
1323
                                if ($this->GetL_m1() <> "") {
1324
                                        $cflink['linkshare1'] = $this->GetL_m1();
1325
                                        $cflink['linkshare2'] = $this->GetL_d();
1326
                                        $cflink['linkshare'] = "on";
1327
                                }
1328
                                if ($this->GetL_m2() <> "") {
1329
                                        $cflink['linkshare3'] = $this->GetL_m2();
1330
                                        $cflink['linkshare'] = "on";
1331
                                }
1332
                        } else $cflink['linkshare'] = "";
1333
                        if ($this->GetRealtime() <> "") {
1334
                                if ($this->GetR_m1() <> "") {
1335
                                        $cflink['realtime1'] = $this->GetR_m1();
1336
                                        $cflink['realtime2'] = $this->GetR_d();
1337
                                        $cflink['realtime'] = "on";
1338
                                }
1339
                                if ($this->GetR_m2() <> "") {
1340
                                        $cflink['realtime3'] = $this->GetR_m2();
1341
                                        $cflink['realtime'] = "on";
1342
                                }
1343
                        } else $cflink['realtime'] = "";
1344
                        if ($this->GetUpperlimit() <> "") {
1345
                                if ($this->GetU_m1() <> "") {
1346
                                        $cflink['upperlimit1'] = $this->GetU_m1();
1347
                                        $cflink['upperlimit2'] = $this->GetU_d();
1348
                                        $cflink['upperlimit'] = "on";
1349
                                }
1350
                                if ($this->GetU_m2() <> "") {
1351
                                        $cflink['upperlimit3'] = $this->GetU_m2();
1352
                                        $cflink['upperlimit'] = "on";
1353
                                }
1354
                        } else $cflink['upperlimit'] = "";
1355

    
1356
	                if (is_array($this->subqueues)) {
1357
        	                $cflinkp['queue'] = array();
1358
                	        foreach ($this->subqueues as $q) {
1359
                	                 $cflink['queue'][$q->GetQname()] = array();
1360
        	                        $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
1361
				}
1362
                	}
1363

    
1364
         	}
1365

    
1366
		function delete_queue() { 
1367
			unref_on_altq_queue_list($this->GetQname());
1368
			if ($this->GetDefault()) 
1369
				altq_set_default_queue($this->GetInterface(), "false");
1370
			cleanup_queue_from_rules($this->GetQname());
1371
			$parent =& $this->GetParent();
1372
			foreach ($this->subqueues as $q)  {
1373
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1374
				$q->delete_queue();
1375
			}
1376
			unset_object_by_reference($this->GetLink());
1377
			}
1378
	
1379
			/*
1380
			 * Should search even its childs
1381
			 */
1382
			function &find_queue($interface, $qname) {
1383
					if ($qname == $this->GetQname()) 
1384
							return $this;
1385
		
1386
					foreach ($this->subqueues as $q) {
1387
							$result =& $q->find_queue("", $qname);
1388
				if ($result)
1389
									return $result;
1390
					}
1391
			}
1392

    
1393
	function &find_parentqueue($interface, $qname) {
1394
		if ($this->subqueues[$qname]) 
1395
			return $this;
1396
				foreach ($this->subqueues as $q) {
1397
					$result = $q->find_parentqueue("", $qname);
1398
			if ($result)
1399
				return $result;
1400
		}
1401
		}
1402
	
1403
	function validate_input($data, &$input_errors) {
1404
		parent::validate_input($data, $input_errors);
1405
		
1406
		$reqfields[] = "bandwidth";
1407
		$reqdfieldsn[] = "Bandwidth";
1408
		$reqfields[] = "bandwidthtype";
1409
		$reqdfieldsn[] = "Bandwidthtype";
1410

    
1411
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1412
		
1413
		if (isset($data['linkshare3']) && $data['linkshare3'] <> "") {
1414
		if ($data['bandwidth'] && (!is_numeric($data['bandwidth'])))
1415
                        $input_errors[] = "Bandwidth must be an integer.";
1416

    
1417
                if ($data['bandwidth'] < 0)
1418
                        $input_errors[] = "Bandwidth cannot be negative.";
1419

    
1420
                if ($data['bandwidthtype'] == "%") {
1421
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1422
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1423
                 }
1424
/*
1425
                $parent =& $this->GetParent();
1426
                switch ($data['bandwidthtype']) {
1427
                       case "%":
1428
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1429
                       default:
1430
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1431
                             break;
1432
                }
1433
                if ($parent->GetAvailableBandwidth() < $myBw)
1434
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1435
*/
1436
                if ($data['priority'] > 7)
1437
                        $input_errors[] = "Priority must be an integer between 1 and 7.";
1438
		}
1439

    
1440
		if ($data['upperlimit1'] <> "" &&  $data['upperlimit2'] == "")
1441
			$input_errors[] = ("upperlimit service curve defined but missing (d) value");
1442
		if ($data['upperlimit2'] <> "" &&  $data['upperlimit1'] == "")
1443
			$input_errors[] = ("upperlimit service curve defined but missing initial bandwidth (m1) value");
1444
		if ($data['upperlimit1'] <> "" && !is_valid_shaperbw($data['upperlimit1']))
1445
			$input_errors[] = ("upperlimit m1 value needs to be Kb, Mb, Gb, or %");
1446
		if ($data['upperlimit2'] <> "" && !is_numeric($data['upperlimit2']))
1447
			$input_errors[] = ("upperlimit d value needs to be numeric");
1448
		if ($data['upperlimit3'] <> "" && !is_valid_shaperbw($data['upperlimit3']))
1449
			$input_errors[] = ("upperlimit m2 value needs to be Kb, Mb, Gb, or %");
1450
/*
1451

    
1452
		if (isset($data['upperlimit']) && $data['upperlimit3'] <> "" && $data['upperlimit1'] <> "") {
1453
		$bw_1 = get_hfsc_bandwidth($this, $data['upperlimit1']);
1454
		$bw_2 = get_hfsc_bandwidth($this, $data['upperlimit3']);
1455
		if (floatval($bw_1) < floatval($bw_2)) 
1456
			$input_errors[] = ("upperlimit m1 cannot be smaller than m2");
1457

    
1458
		
1459
		if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1460
			$input_errors[] = ("upperlimit specification excedd 80% of allowable allocation.");
1461
		}
1462
*/
1463
		if ($data['linkshare1'] <> "" &&  $data['linkshare2'] == "")
1464
			$input_errors[] = ("linkshare service curve defined but missing (d) value");
1465
		if ($data['linkshare2'] <> "" &&  $data['linkshare1'] == "")
1466
			$input_errors[] = ("linkshare service curve defined but missing initial bandwidth (m1) value");
1467
		if ($data['linkshare1'] <> "" && !is_valid_shaperbw($data['linkshare1']))
1468
			$input_errors[] = ("linkshare m1 value needs to be Kb, Mb, Gb, or %");
1469
		if ($data['linkshare2'] <> "" && !is_numeric($data['linkshare2']))
1470
			$input_errors[] = ("linkshare d value needs to be numeric");
1471
		if ($data['linkshare3'] <> "" && !is_valid_shaperbw($data['linkshare3']))
1472
			$input_errors[] = ("linkshare m2 value needs to be Kb, Mb, Gb, or %");
1473
		if ($data['realtime1'] <> "" &&  $data['realtime2'] == "")
1474
			$input_errors[] = ("realtime service curve defined but missing (d) value");
1475
		if ($data['realtime2'] <> "" &&  $data['realtime1'] == "")
1476
			$input_errors[] = ("realtime service curve defined but missing initial bandwidth (m1) value");
1477

    
1478
/*
1479
		if (isset($data['linkshare']) && $data['linkshare3'] <> "" && $data['linkshare1'] <> "" && 0) {
1480
		$bw_1 = get_hfsc_bandwidth($this, $data['linkshare1']);
1481
                $bw_2 = get_hfsc_bandwidth($this, $data['linkshare3']);
1482
                if (floatval($bw_1) < floatval($bw_2))
1483
                        $input_errors[] = ("linkshare m1 cannot be smaller than m2");
1484

    
1485

    
1486
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1487
                        $input_errors[] = ("linkshare specification excedd 80% of allowable allocation.");
1488
		}
1489
*/
1490

    
1491
		if ($data['realtime1'] <> "" && !is_valid_shaperbw($data['realtime1']))
1492
			$input_errors[] = ("realtime m1 value needs to be Kb, Mb, Gb, or %");
1493
		if ($data['realtime2'] <> "" && !is_numeric($data['realtime2']))
1494
			$input_errors[] = ("realtime d value needs to be numeric");
1495
		if ($data['realtime3'] <> "" && !is_valid_shaperbw($data['realtime3']))
1496
			$input_errors[] = ("realtime m2 value needs to be Kb, Mb, Gb, or %");
1497

    
1498
/*
1499
		if (isset($data['realtime']) && $data['realtime3'] <> "" && $data['realtime1'] <> "" && 0) {
1500
		$bw_1 = get_hfsc_bandwidth($this, $data['realtime1']);
1501
                $bw_2 = get_hfsc_bandwidth($this, $data['realtime3']);
1502
                if (floatval($bw_1) < floatval($bw_2))
1503
                        $input_errors[] = ("realtime m1 cannot be smaller than m2");
1504

    
1505

    
1506
                if (get_interface_bandwidth($this) < (0.8 * (floatval($bw_1) + floatval($bw_2))))
1507
                        $input_errors[] = ("realtime specification excedd 80% of allowable allocation.");
1508
		}
1509
*/
1510

    
1511
	}
1512

    
1513
		function ReadConfig(&$cflink) {
1514
		if (isset($cflink['linkshare']) && $cflink['linkshare'] <> "") {
1515
			if (isset($cflink['linkshare1']) && $cflink['linkshare1'] <> "") {
1516
				$this->SetL_m1($cflink['linkshare1']);
1517
                                $this->SetL_d($cflink['linkshare2']);
1518
				$this->SetLinkshare();
1519
			}
1520
			if (isset($cflink['linkshare3']) && $cflink['linkshare3'] <> "") {
1521
                                $this->SetL_m2($cflink['linkshare3']);
1522
				$this->SetLinkshare();
1523
			}
1524
		} else $this->DisableLinkshare();
1525
		if (isset($cflink['realtime']) && $cflink['realtime'] <> "") {
1526
                        if (isset($cflink['realtime1']) && $cflink['realtime1'] <> "") {
1527
                                $this->SetR_m1($cflink['realtime1']);
1528
                                $this->SetR_d($cflink['realtime2']);
1529
				$this->SetRealtime();
1530
			}
1531
                        if (isset($cflink['realtime3']) && $cflink['realtime3'] <> "") {
1532
                                $this->SetR_m2($cflink['realtime3']);
1533
				$this->SetRealtime();
1534
			}
1535
		} else $this->DisableRealtime(); 
1536
		if (isset($cflink['upperlimit']) && $cflink['upperlimit'] <> "") {
1537
                        if (isset($cflink['upperlimit1']) && $cflink['upperlimit1'] <> "") {
1538
                                $this->SetU_m1($cflink['upperlimit1']);
1539
                                $this->SetU_d($cflink['upperlimit2']);
1540
				$this->SetUpperlimit();
1541
			}
1542
                        if (isset($cflink['upperlimit3']) && $cflink['upperlimit3'] <> "") {
1543
                                $this->SetU_m2($cflink['upperlimit3']);
1544
				$this->SetUpperlimit();
1545
			}
1546
		} else $this->DisableUpperlimit();
1547
		parent::ReadConfig($cflink);
1548

    
1549
		}
1550

    
1551
	function build_tree() {
1552
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface() ."&queue=" . $this->GetQname()."&action=show"; 
1553
		$tree .= "\" ";
1554
		if ($this->GetDefault())
1555
								$tree .= " class=\"navlnk\"";
1556
		$tree .= " >" . $this->GetQname() . "</a>";
1557
		if (is_array($this->subqueues)) {
1558
			$tree .= "<ul>";
1559
			foreach ($this->subqueues as $q)  {
1560
				$tree .= $q->build_tree();
1561
			}	
1562
			$tree .= "</ul>";
1563
		}
1564
		$tree .= "</li>";
1565
		return $tree;
1566
	}
1567

    
1568
		/* Even this should take childs in consideration */
1569
		function build_rules() {
1570

    
1571
				$pfq_rule = " queue ". $this->qname;
1572
				if ($this->GetInterface())
1573
						$pfq_rule .= " on ".get_real_interface($this->GetInterface());
1574
		if ($this->GetBandwidth() && $this->GetBwscale())
1575
						$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
1576
					
1577
				if ($this->GetQpriority())
1578
						$pfq_rule .= " priority " . $this->GetQpriority();
1579
				if ($this->GetQlimit())
1580
						$pfq_rule .= " qlimit " . $this->GetQlimit();
1581
		  if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetRealtime() <> "" || $this->GetLinkshare() <> "" || $this->GetUpperlimit() <> "") {
1582
						$pfq_rule .= " hfsc ( ";
1583
						if ($this->GetRed()) {
1584
								$comma = 1;
1585
								$pfq_rule .= " red ";
1586
						}
1587
						if ($this->GetRio()) {
1588
								if ($comma) 
1589
										$pfq_rule .= " ,";
1590
								$comma = 1;
1591
								$pfq_rule .= " rio ";
1592
						}
1593
						if ($this->GetEcn()) {
1594
								if ($comma) 
1595
										$pfq_rule .= " ,";
1596
								$comma = 1;
1597
								$pfq_rule .= " ecn ";
1598
						}
1599
						if ($this->GetDefault()) {
1600
								if ($comma)
1601
										$pfq_rule .= " ,";
1602
								$comma = 1;
1603
								$pfq_rule .= " default ";
1604
						}
1605

    
1606
						if ($this->GetRealtime() <> "")  {
1607
				if ($comma) 
1608
									$pfq_rule .= " , ";
1609
				if ($this->GetR_m1()  <> "" && $this->GetR_d() <> "" && $this->GetR_m2() <> "")
1610
			$pfq_rule .= " realtime (".$this->GetR_m1() . ", " . $this->GetR_d().", ". $this->GetR_m2() .") ";
1611
				else  if ($this->GetR_m2() <> "")
1612
					$pfq_rule .= " realtime " . $this->GetR_m2();
1613
				$comma = 1;
1614
			}
1615
						if ($this->GetLinkshare() <> "") {
1616
								if ($comma)
1617
					$pfq_rule .= " ,";
1618
				if ($this->GetL_m1() <> "" && $this->GetL_d() <> "" && $this->GetL_m2() <> "")
1619
			$pfq_rule .= " linkshare (".$this->GetL_m1(). ", ". $this->GetL_d(). ", ". $this->GetL_m2(). ") ";
1620
				else if ($this->GetL_m2() <> "")
1621
					$pfq_rule .= " linkshare " . $this->GetL_m2() . " ";
1622
				$comma = 1;
1623
			}
1624
						if ($this->GetUpperlimit() <> "") {
1625
				if ($comma)
1626
					$pfq_rule .= " ,";
1627
				if ($this->GetU_m1() <> "" && $this->GetU_d() <> "" && $this->GetU_m2() <> "")
1628
							$pfq_rule .= " upperlimit (".$this->GetU_m1().", ". $this->GetU_d().", ". $this->GetU_m2(). ") ";
1629
				else if ($this->GetU_m2() <> "")
1630
					$pfq_rule .= " upperlimit " . $this->GetU_m2() . " ";
1631
			}
1632
					$pfq_rule .= " ) ";
1633
					}
1634
					if (count($this->subqueues)) {
1635
						$i = count($this->subqueues);
1636
						$pfq_rule .= " { ";
1637
						foreach ($this->subqueues as $qkey => $qnone) {
1638
								if ($i > 1) {
1639
										$i--;
1640
										$pfq_rule .= " {$qkey}, ";
1641
								} else
1642
										$pfq_rule .= " {$qkey} ";
1643
						}
1644
								$pfq_rule .= " } \n";
1645
								foreach ($this->subqueues as $q)
1646
									$pfq_rule .= $q->build_rules();
1647
					}
1648

    
1649
				 $pfq_rule .= " \n";
1650
			
1651
				return $pfq_rule;
1652
		}
1653

    
1654
	function build_javascript() {
1655
		$javascript = parent::build_javascript();
1656
		$javascript .= "<script type=\"text/javascript\">";
1657
		$javascript .= "function enable_realtime(enable_over) { \n";
1658
		$javascript .= "if (document.iform.realtime.checked || enable_over) { \n";
1659
		$javascript .= "document.iform.realtime1.disabled = 0;\n";
1660
		$javascript .= "document.iform.realtime2.disabled = 0;\n";
1661
		$javascript .= "document.iform.realtime3.disabled = 0;\n";
1662
		$javascript .= " } else { \n";
1663
		$javascript .= "document.iform.realtime1.disabled = 1;\n";
1664
		$javascript .= "document.iform.realtime2.disabled = 1;\n";
1665
		$javascript .= "document.iform.realtime3.disabled = 1;\n";
1666
		$javascript .= " } \n";
1667
		$javascript .= " } \n";
1668
		$javascript .= "function enable_linkshare(enable_over) { \n";
1669
		$javascript .= "if (document.iform.linkshare.checked || enable_over) { \n";
1670
		$javascript .= "document.iform.linkshare1.disabled = 0;\n";
1671
		$javascript .= "document.iform.linkshare2.disabled = 0;\n";
1672
		$javascript .= "document.iform.linkshare3.disabled = 0;\n";
1673
		$javascript .= " } else { \n";
1674
		$javascript .= "document.iform.linkshare1.disabled = 1;\n";
1675
		$javascript .= "document.iform.linkshare2.disabled = 1;\n";
1676
		$javascript .= "document.iform.linkshare3.disabled = 1;\n";
1677
		$javascript .= " } \n";
1678
		$javascript .= " } \n";
1679
		$javascript .= "function enable_upperlimit(enable_over) { \n";
1680
		$javascript .= "if (document.iform.upperlimit.checked || enable_over) { \n";
1681
		$javascript .= "document.iform.upperlimit1.disabled = 0;\n";
1682
		$javascript .= "document.iform.upperlimit2.disabled = 0;\n";
1683
		$javascript .= "document.iform.upperlimit3.disabled = 0;\n";
1684
		$javascript .= " } else { \n";
1685
		$javascript .= "document.iform.upperlimit1.disabled = 1;\n";
1686
		$javascript .= "document.iform.upperlimit2.disabled = 1;\n";
1687
		$javascript .= "document.iform.upperlimit3.disabled = 1;\n";
1688
		$javascript .= " } \n";
1689
			
1690
		$javascript .= "} \n";
1691
		$javascript .= "</script>";
1692

    
1693
		return $javascript;
1694
	}
1695

    
1696
		function build_form() {
1697
				$form = "<tr>";
1698
				$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
1699
				$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
1700
				$form .= htmlspecialchars($this->GetBandwidth());
1701
				$form .= "\">";
1702
				$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
1703
				$form .= "<option value=\"Gb\"";
1704
				if ($this->GetBwscale() == "Gb")
1705
						$form .= " selected=\"yes\"";
1706
				$form .= ">Gbit/s</option>";
1707
				$form .= "<option value=\"Mb\"";
1708
				if ($this->GetBwscale() == "Mb")
1709
						$form .= " selected=\"yes\"";
1710
				$form .= ">Mbit/s</option>";
1711
				$form .= "<option value=\"Kb\"";
1712
				if ($this->GetBwscale() == "Kb")
1713
						$form .= " selected=\"yes\"";
1714
				$form .= ">Kbit/s</option>";
1715
				$form .= "<option value=\"\"";
1716
				if ($this->GetBwscale() == "b")
1717
						$form .= " selected=\"yes\"";
1718
				$form .= ">Bit/s</option>";
1719
				$form .= "<option value=\"%\"";
1720
				if ($this->GetBwscale() == "%")
1721
						$form .= " selected=\"yes\"";
1722
				$form .= ">%</option>";
1723
				$form .= "</select> <br>";
1724
				$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
1725
				$form .= "</span></td>";
1726
				$form .= parent::build_form();
1727
				$form .= "<tr>";
1728
				$form .= "<td width=\"22%\" valign=\"top\" class=\"vncellreq\">Service Curve (sc)</td>";
1729
				$form .= "<td width=\"78%\" class=\"vtable\">";
1730
				$form .= "<table>";
1731
				$form .= "<tr><td>&nbsp;</td><td><center>m1</center></td><td><center>d</center></td><td><center><b>m2</b></center></td></tr>";
1732
				$form .= "<tr><td><input type=\"checkbox\" id=\"upperlimit\" name=\"upperlimit\"";
1733
				if($this->GetUpperlimit()<> "") 
1734
					$form .=  " CHECKED ";
1735
				$form .= "onChange=\"enable_upperlimit()\"> Upperlimit:</td><td><input size=\"6\" value=\"";
1736
				$form .= htmlspecialchars($this->GetU_m1());
1737
				$form .= "\" id=\"upperlimit1\" name=\"upperlimit1\" ";
1738
				if ($this->GetUpperlimit() == "") $form .= " disabled";
1739
				$form .= "></td><td><input size=\"6\" value=\"";
1740
				$form .= htmlspecialchars($this->GetU_d());
1741
				$form .= "\" id=\"upperlimi2\" name=\"upperlimit2\" ";
1742
		if ($this->GetUpperlimit() == "") $form .= " disabled";
1743
		$form .= "></td><td><input size=\"6\" value=\"";
1744
				$form .= htmlspecialchars($this->GetU_m2());
1745
				$form .= "\" id=\"upperlimit3\" name=\"upperlimit3\" ";
1746
		if ($this->GetUpperlimit() == "") $form .= " disabled";
1747
		$form .= "></td><td>The maximum allowed bandwidth for the queue.</td></tr>";
1748
				$form .= "<tr><td><input type=\"checkbox\" id=\"realtime\" name=\"realtime\"";
1749
				if($this->GetRealtime() <> "") 
1750
			$form .=  " CHECKED ";
1751
				$form .= "onChange=\"enable_realtime()\"> Real time:</td><td><input size=\"6\" value=\"";
1752
				$form .= htmlspecialchars($this->GetR_m1());
1753
				$form .= "\" id=\"realtime1\" name=\"realtime1\" ";
1754
		if ($this->GetRealtime() == "") $form .= " disabled";
1755
		$form .= "></td><td><input size=\"6\" value=\"";
1756
				$form .= htmlspecialchars($this->GetR_d());
1757
				$form .= "\" id=\"realtime2\" name=\"realtime2\" ";
1758
		if ($this->GetRealtime() == "") $form .= " disabled";
1759
		$form .= "></td><td><input size=\"6\" value=\"";
1760
				$form .= htmlspecialchars($this->GetR_m2());
1761
				$form .= "\" id=\"realtime3\" name=\"realtime3\" ";
1762
		if ($this->GetRealtime() == "") $form .= " disabled";
1763
		$form .= "></td><td>The minimum required bandwidth for the queue.</td></tr>";
1764
				$form .= "<tr><td><input type=\"checkbox\" id=\"linkshare\" id=\"linkshare\" name=\"linkshare\"";
1765
				if($this->GetLinkshare() <> "") 
1766
			$form .=  " CHECKED ";
1767
				$form .= "onChange=\"enable_linkshare()\"> Link share:</td><td><input size=\"6\" value=\"";
1768
				$form .= htmlspecialchars($this->GetL_m1());
1769
				$form .= "\" id=\"linkshare1\" name=\"linkshare1\" ";
1770
		if ($this->GetLinkshare() == "") $form .= " disabled";
1771
		$form .= "></td><td><input size=\"6\" value=\"";
1772
				$form .= htmlspecialchars($this->GetL_d());
1773
				$form .= "\" id=\"linkshare2\" name=\"linkshare2\" ";
1774
		if ($this->GetLinkshare() == "") $form .= " disabled";
1775
		$form .= "></td><td><input size=\"6\" value=\"";
1776
				$form .= htmlspecialchars($this->GetL_m2());
1777
				$form .= "\" id=\"linkshare3\" name=\"linkshare3\" ";
1778
		if ($this->GetLinkshare() == "") $form .= " disabled";
1779
		$form .= "></td><td>The bandwidth share of a backlogged queue - this overrides priority.</td></tr>";
1780
				$form .= "</table><br>";
1781
				$form .= "The format for service curve specifications is (m1, d, m2).  m2 controls";
1782
				$form .= "the bandwidth assigned to the queue.  m1 and d are optional and can be";
1783
				$form .= "used to control the initial bandwidth assignment.  For the first d milliseconds the queue gets the bandwidth given as m1, afterwards the value";
1784
				$form .= "given in m2.";
1785
				$form .= "</span></td>";
1786
				$form .= "</tr>";
1787

    
1788
				return $form;
1789
		}
1790

    
1791
	function update_altq_queue_data(&$data) { 
1792
		$this->ReadConfig($data);
1793
	}
1794

    
1795
	function wconfig() {
1796
		$cflink =& get_reference_to_me_in_config($this->GetLink());
1797
		if (!is_array($cflink))
1798
			$cflink = array();
1799
			$cflink['name'] = $this->GetQname();
1800
			$cflink['interface'] = $this->GetInterface();
1801
			$cflink['qlimit'] = $this->GetQlimit();
1802
			$cflink['priority'] = $this->GetQpriority();
1803
			$cflink['description'] = $this->GetDescription();
1804
			$cflink['bandwidth'] = $this->GetBandwidth();
1805
			$cflink['bandwidthtype'] = $this->GetBwscale();
1806
			$cflink['enabled'] = $this->GetEnabled();
1807
			$cflink['default'] = $this->GetDefault();
1808
			$cflink['red'] = $this->GetRed();
1809
			$cflink['rio'] = $this->GetRio();
1810
			$cflink['ecn'] = $this->GetEcn();
1811
			if ($this->GetLinkshare() <> "") {
1812
				if ($this->GetL_m1() <> "") {
1813
					$cflink['linkshare1'] = $this->GetL_m1();
1814
					$cflink['linkshare2'] = $this->GetL_d();
1815
					$cflink['linkshare'] = "on";
1816
				}
1817
				if ($this->GetL_m2() <> "") {
1818
					$cflink['linkshare3'] = $this->GetL_m2();
1819
					$cflink['linkshare'] = "on";
1820
				}
1821
			} else $cflink['linkshare'] = "";
1822
			if ($this->GetRealtime() <> "") {
1823
				if ($this->GetR_m1() <> "") {
1824
					$cflink['realtime1'] = $this->GetR_m1();
1825
					$cflink['realtime2'] = $this->GetR_d();
1826
					$cflink['realtime'] = "on";
1827
				}
1828
				if ($this->GetR_m2() <> "") {
1829
					$cflink['realtime3'] = $this->GetR_m2();
1830
					$cflink['realtime'] = "on";
1831
				}
1832
			} else $cflink['realtime'] = "";
1833
			if ($this->GetUpperlimit() <> "") {
1834
				if ($this->GetU_m1() <> "") {
1835
					$cflink['upperlimit1'] = $this->GetU_m1();
1836
					$cflink['upperlimit2'] = $this->GetU_d();
1837
					$cflink['upperlimit'] = "on";
1838
				}
1839
				if ($this->GetU_m2() <> "") {
1840
					$cflink['upperlimit3'] = $this->GetU_m2();
1841
					$cflink['upperlimit'] = "on";
1842
				}
1843
			} else $cflink['upperlimit'] = "";
1844
		}
1845
	}
1846

    
1847
class cbq_queue extends priq_queue {
1848
		var $qborrow;
1849

    
1850
	function GetBorrow() {
1851
		return $this->qborrow;
1852
	}
1853
	function SetBorrow($borrow) {
1854
		$this->qborrow = $borrow;
1855
	}
1856
	function CanHaveChilds() {
1857
			return true;
1858
	}
1859

    
1860
	function &add_queue($interface, &$qname, &$path, &$input_errors) {
1861

    
1862
		if (!is_array($this->subqueues))
1863
						$this->subqueues = array();
1864
		$q =& new cbq_queue();
1865
		$q->SetInterface($this->GetInterface());
1866
		$q->SetParent(&$this);
1867
		$q->ReadConfig($qname);
1868
                $q->validate_input($qname, $input_errors);
1869
                if (count($input_errors)) {
1870
                        return $q;
1871
                }
1872
                switch ($q->GetBwscale()) {
1873
                        case "%":
1874
                                $myBw = $this->GetAvailableBandwidth() * $qname['bandwidth'] / 100;
1875
                                break;
1876
                        default:
1877
                                $myBw = $qname['bandwidth'] * get_bandwidthtype_scale($q->GetBwscale());
1878
                                break;
1879
                }
1880
                $q->SetAvailableBandwidth($myBw);
1881
                $this->SetAvailableBandwidth($this->GetAvailableBandwidth() - $myBw);
1882

    
1883
		$q->SetEnabled("on");
1884
		$q->SetLink($path);
1885
		$this->subqueues[$q->GetQName()] = &$q;
1886
		ref_on_altq_queue_list($this->GetQname(), $q->GetQname());
1887
		if (is_array($qname['queue'])) {
1888
				foreach ($qname['queue'] as $key1 => $que) {
1889
						array_push($path, $key1);
1890
						$q->add_queue($q->GetInterface(), &$que, &$path, $input_errors);
1891
						array_pop($path);
1892
				}
1893
		}
1894

    
1895
		return $q;
1896
		}
1897

    
1898
		function copy_queue($interface, &$cflink) {
1899

    
1900
                                $cflink['interface'] = $interface;
1901
                                $cflink['qlimit'] = $this->GetQlimit();
1902
                                $cflink['priority'] = $this->GetQpriority();
1903
                                $cflink['name'] = $this->GetQname();
1904
                                $cflink['description'] = $this->GetDescription();
1905
                                $cflink['bandwidth'] = $this->GetBandwidth();
1906
                                $cflink['bandwidthtype'] = $this->GetBwscale();
1907
                                $cflink['enabled'] = $this->GetEnabled();
1908
                                $cflink['default'] = $this->GetDefault();
1909
                                $cflink['red'] = $this->GetRed();
1910
                                $cflink['rio'] = $this->GetRio();
1911
                                $cflink['ecn'] = $this->GetEcn();
1912
                                $cflink['borrow'] = $this->GetBorrow();
1913
                		if (is_array($this->queues)) {
1914
 		                       $cflinkp['queue'] = array();
1915
                        		foreach ($this->subqueues as $q) {
1916
 		                                $cflink['queue'][$q->GetQname()] = array();
1917
                		                $q->copy_queue($interface, &$cflink['queue'][$q->GetQname()]);
1918
					}
1919
                		}
1920

    
1921
		}
1922
	
1923
		/*
1924
		 * Should search even its childs
1925
		 */
1926
		function &find_queue($interface, $qname) {
1927
				if ($qname == $this->GetQname())
1928
						return $this;
1929
				foreach ($this->subqueues as $q) {
1930
						$result =& $q->find_queue("", $qname);
1931
			if ($result)
1932
								return $result;
1933
				}
1934
		}
1935

    
1936
	function &find_parentqueue($interface, $qname) {
1937
				if ($this->subqueues[$qname])
1938
						return $this;
1939
				foreach ($this->subqueues as $q) {
1940
					$result = $q->find_parentqueue("", $qname);
1941
			if ($result)
1942
				return $result;
1943
		}
1944
		}
1945

    
1946
		function delete_queue() {
1947
			unref_on_altq_queue_list($this->GetQname());
1948
			if ($this->GetDefault())
1949
				altq_set_default_queue($this->GetInterface(), "false");
1950
			cleanup_queue_from_rules($this->GetQname());
1951
			foreach ($this->subqueues as $q) {
1952
			$this->SetAvailableBandwidth($this->GetAvailableBandwidth() + $q->GetAvailableBandwidth());
1953
				$q->delete_queue();
1954
			}
1955
			unset_object_by_reference($this->GetLink());
1956
		}
1957
	
1958
	function validate_input($data, &$input_errors) {
1959
		parent::validate_input($data, $input_errors);
1960
		
1961
		if ($data['priority'] > 7)
1962
				$input_errors[] = "Priority must be an integer between 1 and 7.";
1963
		$reqfields[] = "bandwidth";
1964
		$reqdfieldsn[] = "Bandwidth";
1965
		$reqfields[] = "bandwidthtype";
1966
		$reqdfieldsn[] = "Bandwidthtype";
1967

    
1968
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
1969
		
1970
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
1971
                 $input_errors[] = "Bandwidth must be an integer.";
1972

    
1973

    
1974
           if ($data['bandwidth'] < 0)
1975
                       $input_errors[] = "Bandwidth cannot be negative.";
1976

    
1977

    
1978
           if ($data['bandwidthtype'] == "%") {
1979
                 if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
1980
                       $input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
1981
           }
1982

    
1983
/*
1984
           $parent =& $this->GetParent();
1985
           switch ($data['bandwidthtype']) {
1986
                       case "%":
1987
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
1988
                       default:
1989
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
1990
                             break;
1991
           }
1992
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
1993
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
1994
*/
1995
	}
1996
		function ReadConfig(&$q) {
1997
				parent::ReadConfig($q);
1998
		if ($q['borrow'])
1999
			$this->SetBorrow("on");
2000
		}
2001
		
2002
	function build_javascript() {
2003
		return parent::build_javascript();
2004
	}
2005

    
2006
	function build_tree() {
2007
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . $this->GetInterface()."&queue=" . $this->GetQname()."&action=show"; 
2008
			$tree .= "\" ";
2009
			if ($this->GetDefault())
2010
								$tree .= " class=\"navlnk\"";
2011
			$tree .= " >" . $this->GetQname() . "</a>";
2012
			if (is_array($this->subqueues)) {
2013
				$tree .= "<ul>";
2014
				foreach ($this->subqueues as $q)  {
2015
					$tree .= $q->build_tree();
2016
				}	
2017
				$tree .= "</ul>";
2018
			}
2019
			$tree .= "</li>";
2020
			return $tree;
2021
	}
2022
		
2023
	/* Even this should take childs in consideration */
2024
	function build_rules() {
2025
		   $pfq_rule = "queue ". $this->qname;
2026
			if ($this->GetInterface())
2027
					$pfq_rule .= " on ".get_real_interface($this->GetInterface());
2028
			if ($this->GetBandwidth() && $this->GetBwscale())
2029
					$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2030
			if ($this->GetQpriority())
2031
					$pfq_rule .= " priority " . $this->GetQpriority();
2032
			if ($this->GetQlimit())
2033
					$pfq_rule .= " qlimit " . $this->GetQlimit();
2034
			if ($this->GetDefault() || $this->GetRed() || $this->GetRio() || $this->GetEcn() || $this->GetBorrow()) {
2035
				$pfq_rule .= " cbq ( ";
2036
				if ($this->GetRed()) {
2037
						$comma = 1;
2038
						$pfq_rule .= " red ";
2039
				}
2040
				if ($this->GetRio()) {
2041
						if ($comma) 
2042
								$pfq_rule .= " ,";
2043
						$comma = 1;
2044
						$pfq_rule .= " rio ";
2045
				}
2046
				if ($this->GetEcn()) {
2047
						if ($comma) 
2048
								$pfq_rule .= " ,";
2049
						$comma = 1;
2050
						$pfq_rule .= " ecn ";
2051
				}
2052
				if ($this->GetDefault()) {
2053
						if ($comma)
2054
								$pfq_rule .= " ,";
2055
						$comma = 1;
2056
						$pfq_rule .= " default ";
2057
				}
2058
				if ($this->GetBorrow()) {
2059
					if ($comma)
2060
						$pfq_rule .= ", ";
2061
					$pfq_rule .= " borrow ";
2062
				}
2063
				$pfq_rule .= " ) ";
2064
			} 
2065
			if (count($this->subqueues)) {
2066
					$i = count($this->subqueues);
2067
					$pfq_rule .= " { ";
2068
					foreach ($this->subqueues as $qkey => $qnone) {
2069
							if ($i > 1) {
2070
									$i--;
2071
									$pfq_rule .= " {$qkey}, ";
2072
							} else
2073
									$pfq_rule .= " {$qkey} ";
2074
					}
2075
					$pfq_rule .= " } \n";
2076
					foreach ($this->subqueues as $q)
2077
							$pfq_rule .= $q->build_rules();
2078
			}
2079

    
2080
			$pfq_rule .= " \n";
2081
			return $pfq_rule;
2082
	}
2083

    
2084
	function build_form() {
2085
		$form = "<tr>";
2086
		$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
2087
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2088
		if ($this->GetBandwidth() > 0)
2089
				$form .= htmlspecialchars($this->GetBandwidth());
2090
		$form .= "\">";
2091
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2092
		$form .= "<option value=\"Gb\"";
2093
		if ($this->GetBwscale() == "Gb")
2094
				$form .= " selected=\"yes\"";
2095
		$form .= ">Gbit/s</option>";
2096
		$form .= "<option value=\"Mb\"";
2097
		if ($this->GetBwscale() == "Mb")
2098
				$form .= " selected=\"yes\"";
2099
		$form .= ">Mbit/s</option>";
2100
		$form .= "<option value=\"Kb\"";
2101
		if ($this->GetBwscale() == "Kb")
2102
				$form .= " selected=\"yes\"";
2103
		$form .= ">Kbit/s</option>";
2104
		$form .= "<option value=\"\"";
2105
		if ($this->GetBwscale() == "b")
2106
				$form .= " selected=\"yes\"";
2107
		$form .= ">Bit/s</option>";
2108
		$form .= "<option value=\"%\"";
2109
		if ($this->GetBwscale() == "%")
2110
				$form .= " selected=\"yes\"";
2111
		$form .= ">%</option>";
2112
		$form .= "</select> <br>";
2113
		$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
2114
		$form .= "</span></td></tr>";
2115
		$form .= parent::build_form();
2116
		$form .= "<tr><td class=\"vncellreq\">Scheduler specific options</td>";
2117
		$form .= "<td class=\"vtable\"><input type=\"checkbox\" id=\"borrow\" name=\"borrow\"";
2118
			if($this->GetBorrow() == "on") 
2119
		$form .=  " CHECKED ";
2120
		$form .= "> Borrow from other queues when available<br></td></tr>";
2121

    
2122
		return $form;
2123
	}
2124

    
2125
	function update_altq_queue_data(&$data) { 
2126
		$this->ReadConfig($data);
2127
	}
2128

    
2129
	function wconfig() {
2130
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2131
				if (!is_array($cflink))
2132
						$cflink = array();
2133
				$cflink['interface'] = $this->GetInterface();
2134
				$cflink['qlimit'] = $this->GetQlimit();
2135
				$cflink['priority'] = $this->GetQpriority();
2136
				$cflink['name'] = $this->GetQname();
2137
				$cflink['description'] = $this->GetDescription();
2138
				$cflink['bandwidth'] = $this->GetBandwidth();
2139
				$cflink['bandwidthtype'] = $this->GetBwscale();
2140
				$cflink['enabled'] = $this->GetEnabled();
2141
				$cflink['default'] = $this->GetDefault();
2142
				$cflink['red'] = $this->GetRed();
2143
				$cflink['rio'] = $this->GetRio();
2144
				$cflink['ecn'] = $this->GetEcn();
2145
				$cflink['borrow'] = $this->GetBorrow();
2146
		}
2147
}
2148

    
2149
class fairq_queue extends priq_queue {
2150
		var $hogs;
2151
		var $buckets;
2152

    
2153
	function GetBuckets() {
2154
		return $this->buckets;
2155
	}
2156
	function SetBuckets($buckets) {
2157
		$this->buckets = $buckets;
2158
	}
2159
	function GetHogs() {
2160
		return $this->hogs;
2161
	}
2162
	function SetHogs($hogs) {
2163
		$this->hogs = $hogs;
2164
	}
2165
	function CanHaveChilds() {
2166
		return false;
2167
	}
2168

    
2169

    
2170
	function copy_queue($interface, &$cflink) {
2171
                $cflink['interface'] = $interface;
2172
                $cflink['qlimit'] = $this->GetQlimit();
2173
                $cflink['priority'] = $this->GetQpriority();
2174
                $cflink['name'] = $this->GetQname();
2175
                $cflink['description'] = $this->GetDescription();
2176
                $cflink['bandwidth'] = $this->GetBandwidth();
2177
                $cflink['bandwidthtype'] = $this->GetBwscale();
2178
                $cflink['enabled'] = $this->GetEnabled();
2179
                $cflink['default'] = $this->GetDefault();
2180
                $cflink['red'] = $this->GetRed();
2181
                $cflink['rio'] = $this->GetRio();
2182
                $cflink['ecn'] = $this->GetEcn();
2183
                $cflink['buckets'] = $this->GetBuckets();
2184
		$cflink['hogs'] = $this->GetHogs();
2185
	}
2186
	
2187
	/*
2188
	 * Should search even its childs
2189
	 */
2190
	function &find_queue($interface, $qname) {
2191
		if ($qname == $this->GetQname())
2192
			return $this;
2193
	}
2194

    
2195
	function find_parentqueue($interface, $qname) { return; }
2196

    
2197
	function delete_queue() {
2198
		unref_on_altq_queue_list($this->GetQname());
2199
		if ($this->GetDefault())
2200
			altq_set_default_queue($this->GetInterface(), "false");
2201
		cleanup_queue_from_rules($this->GetQname());
2202
		unset_object_by_reference($this->GetLink());
2203
	}
2204
	
2205
	function validate_input($data, &$input_errors) {
2206
		parent::validate_input($data, $input_errors);
2207
		
2208
		if ($data['priority'] > 255)
2209
				$input_errors[] = "Priority must be an integer between 1 and 255.";
2210
		$reqfields[] = "bandwidth";
2211
		$reqdfieldsn[] = "Bandwidth";
2212
		$reqfields[] = "bandwidthtype";
2213
		$reqdfieldsn[] = "Bandwidthtype";
2214

    
2215
		shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2216
		
2217
		if ($data['bandwidth'] && !is_numeric($data['bandwidth']))
2218
	                 $input_errors[] = "Bandwidth must be an integer.";
2219

    
2220

    
2221
	        if ($data['bandwidth'] < 0)
2222
                       $input_errors[] = "Bandwidth cannot be negative.";
2223

    
2224

    
2225
        	if ($data['bandwidthtype'] == "%") {
2226
                	if ($data['bandwidth'] > 100 || $data['bandwidth'] < 0)
2227
                       		$input_errors[] = "Bandwidth in percentage should be between 1 and 100 bounds.";
2228
           	}
2229

    
2230
/*
2231
           	$parent =& $this->GetParent();
2232
           	switch ($data['bandwidthtype']) {
2233
                       case "%":
2234
                             $myBw = $parent->GetAvailableBandwidth() * floatval($data['bandwidth']) / 100;
2235
                       default:
2236
                             $mybw = floatval($data['bandwidth']) * get_bandwidthtype_scale($data['bandwidthtype']);
2237
                             break;
2238
           	}
2239
                if ($parent->GetAvailableBandwidth() < floatval($myBw))
2240
                        $input_errors[] = "The sum of child bandwidths exceeds that of the parent.";
2241
*/
2242
	}
2243
	
2244
	function ReadConfig(&$q) {
2245
		parent::ReadConfig($q);
2246
		if ($q['buckets'])
2247
			$this->SetBuckets($q['buckets']);
2248
		if ($q['hogs'] && is_valid_shaperbw($q['hogs']))
2249
			$this->SetHogs($q['hogs']);
2250
	}
2251
		
2252
	function build_javascript() {
2253
		return parent::build_javascript();
2254
	}
2255

    
2256
	function build_tree() {
2257
		$tree = " <li><a href=\"firewall_shaper.php?interface=" . 
2258
			$this->GetInterface()."&queue=" . $this->GetQname()."&action=show"; 
2259
			$tree .= "\" ";
2260
			if ($this->GetDefault())
2261
				$tree .= " class=\"navlnk\"";
2262
			$tree .= " >" . $this->GetQname() . "</a>";
2263
			$tree .= "</li>";
2264
			return $tree;
2265
	}
2266
		
2267
	/* Even this should take childs in consideration */
2268
	function build_rules() {
2269
		$pfq_rule = "queue ". $this->qname;
2270
		if ($this->GetInterface())
2271
			$pfq_rule .= " on ".get_real_interface($this->GetInterface());
2272
		if ($this->GetBandwidth() && $this->GetBwscale())
2273
			$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2274
		if ($this->GetQpriority())
2275
			$pfq_rule .= " priority " . $this->GetQpriority();
2276
		if ($this->GetQlimit())
2277
			$pfq_rule .= " qlimit " . $this->GetQlimit();
2278
		if ($this->GetDefault() || $this->GetRed() || $this->GetRio() 
2279
			|| $this->GetEcn() || $this->GetBuckets() || $this->GetHogs()) {
2280
			$pfq_rule .= " fairq ( ";
2281
			if ($this->GetRed()) {
2282
				$comma = 1;
2283
				$pfq_rule .= " red ";
2284
			}
2285
			if ($this->GetRio()) {
2286
				if ($comma) 
2287
					$pfq_rule .= " ,";
2288
				$comma = 1;
2289
				$pfq_rule .= " rio ";
2290
			}
2291
			if ($this->GetEcn()) {
2292
				if ($comma) 
2293
					$pfq_rule .= " ,";
2294
				$comma = 1;
2295
				$pfq_rule .= " ecn ";
2296
			}
2297
			if ($this->GetDefault()) {
2298
				if ($comma)
2299
					$pfq_rule .= " ,";
2300
				$comma = 1;
2301
				$pfq_rule .= " default ";
2302
			}
2303
			if ($this->GetBuckets()) {
2304
				if ($comma)
2305
					$pfq_rule .= ", ";
2306
				$pfq_rule .= " buckets " . $this->GetBuckets() . " ";
2307
			}
2308
			if ($this->GetHogs()) {
2309
				if ($comma)
2310
					$pfq_rule .= ", ";
2311
				$pfq_rule .= " hogs " . $this->GetHogs() . " ";
2312
			}
2313
				$pfq_rule .= " ) ";
2314
		} 
2315

    
2316
		$pfq_rule .= " \n";
2317
		return $pfq_rule;
2318
	}
2319

    
2320
	function build_form() {
2321
		$form = "<tr>";
2322
		$form .= "<td valign=\"top\" class=\"vncellreq\">Bandwidth</td>";
2323
		$form .= "<td class=\"vtable\"> <input name=\"bandwidth\" id=\"bandwidth\" class=\"formfld unknown\" value=\"";
2324
		if ($this->GetBandwidth() > 0)
2325
				$form .= htmlspecialchars($this->GetBandwidth());
2326
		$form .= "\">";
2327
		$form .= "<select name=\"bandwidthtype\" id=\"bandwidthtype\" class=\"formselect\">";
2328
		$form .= "<option value=\"Gb\"";
2329
		if ($this->GetBwscale() == "Gb")
2330
				$form .= " selected=\"yes\"";
2331
		$form .= ">Gbit/s</option>";
2332
		$form .= "<option value=\"Mb\"";
2333
		if ($this->GetBwscale() == "Mb")
2334
				$form .= " selected=\"yes\"";
2335
		$form .= ">Mbit/s</option>";
2336
		$form .= "<option value=\"Kb\"";
2337
		if ($this->GetBwscale() == "Kb")
2338
				$form .= " selected=\"yes\"";
2339
		$form .= ">Kbit/s</option>";
2340
		$form .= "<option value=\"\"";
2341
		if ($this->GetBwscale() == "b")
2342
				$form .= " selected=\"yes\"";
2343
		$form .= ">Bit/s</option>";
2344
		$form .= "<option value=\"%\"";
2345
		if ($this->GetBwscale() == "%")
2346
				$form .= " selected=\"yes\"";
2347
		$form .= ">%</option>";
2348
		$form .= "</select> <br>";
2349
		$form .= "<span class=\"vexpl\">Choose the amount of bandwidth for this queue";
2350
		$form .= "</span></td></tr>";
2351
		$form .= parent::build_form();
2352
		$form .= "<tr><td class=\"vncellreq\">Scheduler specific options</td>";
2353
		$form .= "<td class=\"vtable\"><table><tr><td>";
2354
		$form .= "<input id=\"buckets\" name=\"buckets\" value=\"";
2355
			if($this->GetBuckets()) 
2356
				$form .=  $this->GetBuckets();
2357
		$form .= "\"> Number of buckets available.<br></td></tr>";
2358
		$form .= "<tr><td class=\"vtable\"><input id=\"hogs\" name=\"hogs\" value=\"";
2359
			if($this->GetHogs()) 
2360
				$form .=  $this->GetHogs();
2361
		$form .= "\"> Bandwidth limit for hosts to not saturate link.<br></td></tr>";
2362
		$form .= "</table></td></tr>";
2363
		return $form;
2364
	}
2365

    
2366
	function update_altq_queue_data(&$data) { 
2367
		$this->ReadConfig($data);
2368
	}
2369

    
2370
	function wconfig() {
2371
		$cflink =& get_reference_to_me_in_config($this->GetLink());
2372
		if (!is_array($cflink))
2373
			$cflink = array();
2374
		$cflink['interface'] = $this->GetInterface();
2375
		$cflink['qlimit'] = $this->GetQlimit();
2376
		$cflink['priority'] = $this->GetQpriority();
2377
		$cflink['name'] = $this->GetQname();
2378
		$cflink['description'] = $this->GetDescription();
2379
		$cflink['bandwidth'] = $this->GetBandwidth();
2380
		$cflink['bandwidthtype'] = $this->GetBwscale();
2381
		$cflink['enabled'] = $this->GetEnabled();
2382
		$cflink['default'] = $this->GetDefault();
2383
		$cflink['red'] = $this->GetRed();
2384
		$cflink['rio'] = $this->GetRio();
2385
		$cflink['ecn'] = $this->GetEcn();
2386
		$cflink['buckets'] = $this->GetBuckets();
2387
		$cflink['hogs'] = $this->GetHogs();
2388
	}
2389
}
2390

    
2391

    
2392
/*
2393
 * XXX: TODO Link dummynet(4) in the system. 
2394
 */
2395

    
2396

    
2397
/*
2398
 * List of respective objects!
2399
 */
2400
$dummynet_pipe_list = array();
2401

    
2402
class dummynet_class {
2403
        var $qname;
2404
		var $qnumber; /* dummynet(4) uses numbers instead of names; maybe integrate with pf the same as altq does?! */
2405
        var $qlimit;
2406
        var $description;
2407
		var $qenabled;
2408
		var $link;
2409
		var $qparent; /* link to upper class so we do things easily on WF2Q+ rule creation */
2410
        var $plr;
2411

    
2412
        var $buckets;
2413
        /* mask parameters */
2414
        var $mask;
2415
        var $noerror;
2416

    
2417
        /* Accesor functions */
2418
        function SetLink($link) {
2419
                $this->link = $link;
2420
        }
2421
        function GetLink() {
2422
                return $this->link;
2423
        }
2424
		function Getmask() {
2425
			return $this->mask;
2426
		}
2427
		function SetMask($mask) {
2428
			$this->mask = $mask;
2429
		}
2430
		function &GetParent() {
2431
			return $this->qparent;
2432
		}
2433
		function SetParent(&$parent) {
2434
			$this->qparent = &$parent;
2435
		}
2436
        function GetEnabled() {
2437
                return $this->qenabled;
2438
        }
2439
        function SetEnabled($value) {
2440
                $this->qenabled = $value;
2441
        }
2442
		function CanHaveChilds() {
2443
                return false;
2444
        }
2445
		function CanBeDeleted() {
2446
                return true;
2447
        }
2448
        function GetQname() {
2449
                return $this->qname;
2450
        }
2451
        function SetQname($name) {
2452
                $this->qname = trim($name);
2453
        }
2454
        function GetQlimit() {
2455
                return $this->qlimit;
2456
        }
2457
        function SetQlimit($limit) {
2458
               	$this->qlimit = $limit;
2459
        }
2460
        function GetDescription() {
2461
                return $this->description;
2462
        }
2463
        function SetDescription($str) {
2464
                $this->descritpion = trim($str);
2465
        }
2466
        function GetFirstime() {
2467
                return $this->firsttime;
2468
        }
2469
        function SetFirsttime($number) {
2470
                $this->firsttime = $number;
2471
        }
2472
        function GetBuckets() {
2473
                return $this->buckets;
2474
        }
2475
        function SetBuckets($buckets) {
2476
                $this->buckets = $buckets;
2477
        }
2478
		function SetNumber($number) {
2479
			$this->qnumber = $number;
2480
		}
2481
		function GetNumber() {
2482
			return $this->qnumber;
2483
		}
2484
        function GetPlr() {
2485
                return $this->plr;
2486
        }
2487
        function SetPlr($plr) {
2488
                $this->plr = $plr;
2489
        }
2490

    
2491
		function build_javascript() { return; } /* Do not remove */
2492

    
2493
		function validate_input($data, &$input_errors) {
2494
			$reqfields[] = "bandwidth";
2495
			$reqdfieldsn[] = "Bandwidth";
2496
			$reqfields[] = "bandwidthtype";
2497
			$reqdfieldsn[] = "Bandwidthtype";
2498
			$reqfields[] = "name";
2499
			$reqfieldsn[] = "Name";
2500
		
2501
			shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
2502

    
2503
			if ($data['plr'] && ((!is_numeric($data['plr'])) ||
2504
					($data['plr'] <= 0 && $data['plr'] > 1))) 
2505
            	$input_errors[] = "Plr must be an integer between 1 and 100.";
2506
			if (($data['buckets'] && (!is_numeric($data['buckets']))) ||
2507
					($data['buckets'] < 1 && $data['buckets'] > 100)) 
2508
            	$input_errors[] = "Buckets must be an integer between 16 and 65535.";
2509
			if ($data['qlimit'] && (!is_numeric($data['qlimit']))) 
2510
            	$input_errors[] = "Queue limit must be an integer";
2511
        	if (!preg_match("/^[a-zA-Z0-9_-]+$/", $data['name']))
2512
               	 $input_errors[] = "Queue names must be alphanumeric and _ or - only.";
2513
		}
2514
}
2515

    
2516
class dnpipe_class extends dummynet_class {
2517
        var $pipe_nr;
2518
        var $delay;
2519
	var $qbandwidth;
2520
	var $qbandwidthtype;
2521

    
2522
		/* This is here to help on form building and building rules/lists */
2523
        var $subqueues = array();
2524

    
2525
	function CanHaveChilds() {
2526
	        return true;
2527
        }
2528
	function SetDelay($delay) {
2529
		$this->delay = $delay;
2530
	}
2531
	function GetDelay() {
2532
		return $this->delay;
2533
	}
2534
	function GetBwscale() {
2535
                return $this->qbandwidthtype;
2536
        }
2537
        function SetBwscale($scale) {
2538
               	$this->qbandwidthtype = $scale;
2539
        }		
2540
	function delete_queue() {
2541
		cleanup_dnqueue_from_rules($this->GetQname());
2542
		foreach ($this->subqueues as $q)
2543
			$q->delete_queue();
2544
		unset_dn_object_by_reference($this->GetLink());
2545
        }
2546
        function GetBandwidth() {
2547
                return $this->qbandwidth;
2548
        }
2549
        function SetBandwidth($bandwidth) {
2550
                $this->qbandwidth = $bandwidth;
2551
        }
2552

    
2553
	function &add_queue($interface, &$queue, &$path, &$input_errors) {
2554

    
2555
		if (!is_array($this->subqueues))
2556
			$this->subqueues = array();
2557
			
2558
		$q =& new dnqueue_class();
2559
		$q->SetLink($path);
2560
		$q->SetEnabled("on");
2561
		$q->SetPipe($this->GetQname());
2562
		$q->SetParent(&$this);
2563
		$q->ReadConfig($queue);
2564
		$q->validate_input($queue, $input_errors);
2565
		if (count($input_errors))
2566
			return $q;
2567
		$this->subqueues[$q->GetQname()] = &$q;
2568
            
2569
		return $q;
2570
	}
2571

    
2572
	function &get_queue_list($q = null) {
2573
		$qlist = array();
2574

    
2575
		$qlist[$this->GetQname()] = $this->GetNumber();
2576
		if (is_array($this->subqueues)) {
2577
			foreach ($this->subqueues as $queue)
2578
				$queue->get_queue_list(&$qlist);
2579
		}
2580
		return $qlist;
2581
	}
2582
		
2583
        /*
2584
         * Should search even its childs
2585
         */
2586
        function &find_queue($pipe, $qname) {
2587
                if ($qname == $this->GetQname()) 
2588
                        return $this;
2589
               	foreach ($this->subqueues as $q) {
2590
                       	$result =& $q->find_queue("", $qname);
2591
						if ($result)
2592
                       	        return $result;
2593
               	}
2594
        }
2595

    
2596
	function &find_parentqueue($pipe, $qname) {
2597
		return NULL;
2598
       	}
2599

    
2600
	function validate_input($data, &$input_errors) {
2601
		parent::validate_input($data, $input_errors);
2602

    
2603
		if ($data['bandwidth'] && (!is_numeric($data['bandwidth']))) 
2604
       		     	$input_errors[] = "Bandwidth must be an integer.";
2605
		if ($data['delay'] && (!is_numeric($data['delay'])))
2606
            		$input_errors[] = "Delay must be an integer.";
2607
		}
2608

    
2609
	function ReadConfig(&$q) {
2610
           	$this->SetQname($q['name']);
2611
		$this->SetNumber($q['number']);
2612
		if (isset($q['bandwidth']) && $q['bandwidth'] <> "") { 
2613
			$this->SetBandwidth($q['bandwidth']);
2614
			if (isset($q['bandwidthtype']) && $q['bandwidthtype'])
2615
				$this->SetBwscale($q['bandwidthtype']);
2616
		}
2617
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
2618
              		$this->SetQlimit($q['qlimit']);
2619
		if (isset($q['mask']) && $q['mask'] <> "")
2620
              		$this->SetMask($q['mask']);
2621
		if (isset($q['buckets']) && $q['buckets'] <> "")
2622
              		$this->SetBuckets($q['buckets']);
2623
            	if (isset($q['plr']) && $q['plr'] <> "")
2624
            		$this->SetPlr($q['plr']);
2625
		if (isset($q['delay']) && $q['delay'] <> "")
2626
            		$this->SetDelay($q['delay']);
2627
            	if (isset($q['description']) && $q['description'] <> "")
2628
			$this->SetDescription($q['description']);
2629
		$this->SetEnabled($q['enabled']);
2630

    
2631
        }
2632

    
2633
	function build_tree() {
2634
		$tree = " <li><a href=\"firewall_shaper_vinterface.php?pipe=" . $this->GetQname() ."&queue=".$this->GetQname() ."&action=show\">"; 
2635
		$tree .= $this->GetQname() . "</a>";
2636
		if (is_array($this->subqueues)) {
2637
			$tree .= "<ul>";
2638
			foreach ($this->subqueues as $q)  {
2639
				$tree .= $q->build_tree();
2640
			}	
2641
			$tree .= "</ul>";
2642
		}
2643
		$tree .= "</li>";
2644
		
2645
		return $tree;
2646
	}
2647

    
2648
        function build_rules() {
2649
		if ($this->GetEnabled() == "")
2650
			return;
2651

    
2652
       		$pfq_rule = "\ndnpipe ". $this->GetNumber();
2653
		if ($this->GetBandwidth() && $this->GetBwscale())
2654
                    	$pfq_rule .= " bandwidth ".trim($this->GetBandwidth()).$this->GetBwscale();
2655
		if ($this->GetQlimit())
2656
                    	$pfq_rule .= " queue " . $this->GetQlimit();
2657
		if ($this->GetPlr())
2658
			$pfq_rule .= " plr " . $this->GetPlr();
2659
		if ($this->GetBuckets())
2660
			$pfq_rule .= " buckets " . $this->GetBuckets();
2661
		if ($this->GetDelay())
2662
			$pfq_rule .= " delay " . $this->GetDelay();
2663

    
2664
		$mask = $this->GetMask();
2665
		if (!empty($mask)) {
2666
			/* XXX TODO extend this to support more complicated masks */
2667
			switch ($mask) {
2668
			case 'srcaddress':
2669
				$pfq_rule .= " mask src-ip 0xffffffff ";
2670
				break;
2671
			case 'dstaddress':
2672
				$pfq_rule .= " mask dst-ip 0xffffffff ";
2673
				break;
2674
			default:
2675
				break;
2676
			}
2677
			$pfq_rule .= "\n";
2678

    
2679
			if (!empty($this->subqueues) && count($this->subqueues) > 0) {
2680
       			        foreach ($this->subqueues as $q)
2681
				$pfq_rule .= $q->build_rules();
2682
               		}
2683
    		}            
2684
		$pfq_rule .= " \n";
2685

    
2686
		return $pfq_rule;
2687
        }
2688

    
2689
	function update_dn_data(&$data) { 
2690
		$this->ReadConfig($data);
2691
	}
2692

    
2693
        function build_form() { 
2694
		$form = "<tr><td valign=\"top\" class=\"vncellreq\"><br><span class=\"vexpl\">Name</span></td>";
2695
		$form .= "<td class=\"vncellreq\">";
2696
		$form .= "<input type=\"text\" id=\"name\" name=\"name\" value=\"";
2697
		$form .= $this->GetQname()."\">";
2698
		$form .= "</td></tr>";
2699
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Bandwidth";
2700
		$form .= "</td><td class=\"vncellreq\">";
2701
		$form .= "<input type=\"text\" id=\"bandwidth\" name=\"bandwidth\" value=\"";
2702
		$form .= $this->GetBandwidth() . "\">"; 
2703
		$form .= "<select id=\"bandwidthtype\" name=\"bandwidthtype\" class=\"formselect\">";
2704
		$form .= "<option value=\"Kb\"";
2705
		if ($this->GetBwscale() == "Kb")
2706
			$form .= " selected=\"yes\"";
2707
		$form .= ">Kbit/s</option>";
2708
		$form .= "<option value=\"Mb\"";
2709
		if ($this->GetBwscale() == "Mb")
2710
			$form .= " selected=\"yes\"";
2711
		$form .= ">Mbit/s</option>";
2712
		$form .= "<option value=\"Gb\"";
2713
		if ($this->GetBwscale() == "Gb")
2714
			$form .= " selected=\"yes\"";
2715
		$form .= ">Gbit/s</option>";		
2716
		$form .= "<option value=\"\"";
2717
		if ($this->GetBwscale() == "b")
2718
			$form .= " selected=\"yes\"";
2719
		$form .= ">Bit/s</option>";
2720
		$form .= "</select>";
2721
		$form .= "</td></tr>";
2722
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Mask</td>";
2723
		$form .= "<td class=\"vncellreq\">";
2724
		$form .= "<select name=\"mask\" class=\"formselect\">";
2725
		$form .= "<option value=\"none\"";
2726
		if ($this->GetMask() == "none")
2727
			$form .= " selected=\"yes\"";
2728
		$form .= ">none</option>";
2729
		$form .= "<option value=\"srcaddress\"";
2730
		if ($this->GetMask() == "srcaddress")
2731
			$form .= " selected=\"yes\"";
2732
		$form .= ">Source addresses</option>";
2733
		$form .= "<option value=\"dstaddress\"";
2734
		if ($this->GetMask() == "dstaddress")
2735
			$form .= " selected=\"yes\"";
2736
		$form .= ">Destination addresses</option>";
2737
		$form .= "</select>";
2738
		$form .= "&nbsp;<br>";
2739
		$form .= "<span class=\"vexpl\">If 'source' or 'destination' is chosen, \n";
2740
		$form .= "a dynamic pipe with the bandwidth, delay, packet loss and queue size given above will \n";
2741
		$form .= "be created for each source/destination IP address encountered, \n";
2742
		$form .= "respectively. This makes it possible to easily specify bandwidth \n";
2743
		$form .= "limits per host.</span>";
2744
		$form .= "</td></tr>";
2745
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Description</td>";
2746
		$form .= "<td class=\"vncellreq\">";
2747
		$form .= "<input type=\"text\" class=\"formfld unknown\" size=\"50%\" id=\"description\" name=\"description\" value=\"";
2748
		$form .= $this->GetDescription();
2749
		$form .= "\">";
2750
		$form .= "<br> <span class=\"vexpl\">";
2751
		$form .= "You may enter a description here ";
2752
		$form .= "for your reference (not parsed).</span>";
2753
		$form .= "</td></tr>";
2754
      		$form .= "<tr id=\"sprtable4\" name=\"sprtable4\">";
2755
		$form .= "<td></td>";
2756
                $form .= "<td><div id=\"showadvancedboxspr\">";
2757
                $form .= "<p><input type=\"button\" onClick=\"show_source_port_range()\"";
2758
		$form .= " value=\"Show advanced options\"></input></a>";
2759
                $form .= "</div></td></tr>";
2760
                $form .= "<tr style=\"display:none\" id=\"sprtable\" name=\"sprtable\">";
2761

    
2762
		$form .= "<td valign=\"top\" class=\"vncellreq\">Delay</td>";
2763
		$form .= "<td valign=\"top\" class=\"vncellreq\">";
2764
		$form .= "<input name=\"delay\" type=\"text\" id=\"delay\" size=\"5\" value=\"";
2765
		$form .= $this->GetDelay() . "\">";
2766
		$form .= "&nbsp;ms<br> <span class=\"vexpl\">Hint: in most cases, you"; 
2767
		$form .= "should specify 0 here (or leave the field empty)</span>";
2768
		$form .= "</td></tr><br/>";
2769
      		$form .= "<tr style=\"display:none\" id=\"sprtable1\" name=\"sprtable1\">";
2770
		$form .= "<td valign=\"top\" class=\"vncellreq\">Packet loss rate</td>";
2771
		$form .= "<td valign=\"top\" class=\"vncellreq\">";
2772
		$form .= "<input name=\"plr\" type=\"text\" id=\"plr\" size=\"5\" value=\"";
2773
		$form .= $this->GetPlr() . "\">";
2774
		$form .= "&nbsp;<br> <span class=\"vexpl\">Hint: in most cases, you"; 
2775
        $form .= "should specify 0 here (or leave the field empty).";
2776
		$form .= "A value of 0.001 means one packet in 1000 gets dropped</span>";
2777
		$form .= "</td></tr>";
2778
		$form .= "<tr style=\"display:none\" id=\"sprtable2\" name=\"sprtable2\">";
2779
		$form .= "<td valign=\"top\" class=\"vncellreq\">Queue Size</td>";
2780
		$form .= "<td class=\"vncellreq\">";
2781
		$form .= "<input type=\"text\" id=\"qlimit\" name=\"qlimit\" value=\"";
2782
		$form .= $this->GetQlimit() . "\">";
2783
		$form .= "&nbsp;slots<br>";
2784
		$form .= "<span class=\"vexpl\">Hint: in most cases, you ";
2785
		$form .= "should leave the field empty. All packets in this pipe are placed into a fixed-size queue first,";
2786
	        $form .= "then they are delayed by value specified in the Delay field, and then they ";
2787
		$form .= "are delivered to their destination.</span>";
2788
		$form .= "</td></tr>";
2789
		$form .= "<tr style=\"display:none\" id=\"sprtable5\" name=\"sprtable5\">";
2790
                $form .= "<td valign=\"top\" class=\"vncellreq\">Bucket Size</td>";
2791
                $form .= "<td class=\"vncellreq\">";
2792
                $form .= "<input type=\"text\" id=\"buckets\" name=\"buckets\" value=\"";
2793
                $form .= $this->GetBuckets() . "\">";
2794
                $form .= "&nbsp;slots<br>";
2795
                $form .= "<span class=\"vexpl\">Hint: in most cases, you ";
2796
                $form .= "should leave the field empty. It increases the hash size set.";
2797
                $form .= "</td></tr>";
2798

    
2799
		return $form;
2800
			
2801
		}
2802

    
2803
	function wconfig() {
2804
		$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
2805
            	if (!is_array($cflink))
2806
            		$cflink = array();
2807
		$cflink['name'] = $this->GetQname();
2808
		$cflink['number'] = $this->GetNumber();
2809
            	$cflink['qlimit'] = $this->GetQlimit();
2810
            	$cflink['plr'] = $this->GetPlr();
2811
            	$cflink['description'] = $this->GetDescription();
2812
		$cflink['bandwidth'] = $this->GetBandwidth();
2813
            	$cflink['bandwidthtype'] = $this->GetBwscale();
2814
		$cflink['enabled'] = $this->GetEnabled();
2815
		$cflink['buckets'] = $this->GetBuckets();
2816
		$cflink['mask'] = $this->GetMask();
2817
		$cflink['delay'] = $this->GetDelay();
2818
	}
2819

    
2820
}
2821

    
2822
class dnqueue_class extends dummynet_class {
2823
        var $pipeparent;
2824
        var $weight;
2825

    
2826
        function GetWeight() {
2827
                return $this->weight;
2828
        }
2829
        function SetWeight($weight) {
2830
                $this->weight = $weight;
2831
        }
2832
	function GetPipe() {
2833
		return $this->pipeparent;
2834
	}
2835
	function SetPipe($pipe) {
2836
		$this->pipeparent = $pipe;
2837
	}
2838

    
2839
	/* Just a stub in case we ever try to call this from the frontend. */
2840
	function &add_queue($interface, &$queue, &$path, &$input_errors) { return; }
2841

    
2842
	function delete_queue() {
2843
		cleanup_dnqueue_from_rules($this->GetQname());
2844
		unset_dn_object_by_reference($this->GetLink());
2845
        }
2846

    
2847
	function validate_input($data, &$input_errors) {
2848
		parent::validate_input($data, $input_errors);
2849

    
2850
		if ($data['weight'] && ((!is_numeric($data['weight'])) ||
2851
			($data['weight'] < 1 && $data['weight'] > 100))) 
2852
       		     	$input_errors[] = "Weight must be an integer between 1 and 100.";
2853
	}
2854

    
2855
        /*
2856
         * Should search even its childs
2857
         */
2858
        function &find_queue($pipe, $qname) {
2859
                if ($qname == $this->GetQname()) 
2860
                	return $this;
2861
		else
2862
			return NULL;
2863
        }
2864

    
2865
	function &find_parentqueue($pipe, $qname) {
2866
		return $this->qparent;
2867
        }
2868

    
2869
        function &get_queue_list(&$qlist) {
2870
        	$qlist[$this->GetQname()] = "?" .$this->GetNumber();
2871
        }		
2872

    
2873
	function ReadConfig(&$q) {
2874
          	$this->SetQname($q['name']);
2875
		$this->SetNumber($q['number']);
2876
		if (isset($q['qlimit']) && $q['qlimit'] <> "")
2877
       		       	$this->SetQlimit($q['qlimit']);
2878
		if (isset($q['mask']) && $q['mask'] <> "")
2879
              		$this->SetMask($q['mask']);
2880
       		if (isset($q['weight']) && $q['weight'] <> "")
2881
            		$this->SetWeight($q['weight']);
2882
            	if (isset($q['descritption']) && $q['description'] <> "")
2883
			$this->SetDescription($q['description']);
2884
		$this->SetEnabled($q['enabled']);
2885
        }
2886

    
2887
	function build_tree() {
2888
		$parent =& $this->GetParent();
2889
		$tree = " <li><a href=\"firewall_shaper_vinterface.php?pipe=" . $parent->GetQname() ."&queue=" . $this->GetQname() ."&action=show\">"; 
2890
		$tree .= $this->GetQname() . "</a>";
2891
		$tree .= "</li>";
2892
		
2893
		return $tree;
2894
	}
2895

    
2896
        function build_rules() {
2897
		if ($this->GetEnabled() == "")
2898
			return; 
2899

    
2900
		$parent =& $this->GetParent();
2901
            	$pfq_rule = "dnqueue ". $this->GetNumber() . " dnpipe " . $parent->GetNumber();
2902
		if ($this->GetQlimit())
2903
                    	$pfq_rule .= " queue " . $this->GetQimit();
2904
		if ($this->GetWeight())
2905
			$pfq_rule .= " weight " . $this->GetWeight();
2906
		if ($this->GetBuckets())
2907
			$pfq_rule .= " buckets " . $this->GetBuckets();
2908
		$mask = $this->GetMask();
2909
		if (!empty($mask)) {
2910
			/* XXX TODO extend this to support more complicated masks */
2911
			switch ($mask) {
2912
			case 'srcaddress':
2913
				$pfq_rule .= " mask src-ip 0xffffffff ";
2914
				break;
2915
			case 'dstaddress':
2916
				$pfq_rule .= " mask dst-ip 0xffffffff ";
2917
				break;
2918
			default:
2919
				break;
2920
			}
2921
			$pfq_rule .= "\n";
2922
		}
2923

    
2924
		return $pfq_rule;
2925
	}
2926

    
2927
        function build_form() { 
2928
		$form = "<tr><td valign=\"top\" class=\"vncellreq\"><br><span class=\"vexpl\">Name</span></td>";
2929
		$form .= "<td class=\"vncellreq\">";
2930
		$form .= "<input type=\"text\" id=\"name\" name=\"name\" value=\"";
2931
		$form .= $this->GetQname()."\">";
2932
		$form .= "</td></tr>";
2933
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Mask</td>";
2934
		$form .= "<td class=\"vncellreq\">";
2935
		$form .= "<select name=\"mask\" class=\"formselect\">";
2936
		$form .= "<option value=\"none\"";
2937
		if ($this->GetMask() == "none")
2938
			$form .= " selected=\"yes\"";
2939
		$form .= ">none</option>";
2940
		$form .= "<option value=\"srcaddress\"";
2941
		if ($this->GetMask() == "srcaddress")
2942
			$form .= " selected=\"yes\"";
2943
		$form .= ">Source addresses</option>";
2944
		$form .= "<option value=\"dstaddress\"";
2945
		if ($this->GetMask() == "dstaddress")
2946
			$form .= " selected=\"yes\"";
2947
		$form .= ">Destination addresses</option>";
2948
		$form .= "</select>";
2949
		$form .= "&nbsp;slots<br>";
2950
		$form .= "<span class=\"vexpl\">If 'source' or 'destination' is chosen, \n";
2951
		$form .= "a dynamic pipe with the bandwidth, delay, packet loss and queue size given above will \n";
2952
		$form .= "be created for each source/destination IP address encountered, \n";
2953
		$form .= "respectively. This makes it possible to easily specify bandwidth \n";
2954
		$form .= "limits per host.</span>";
2955
		$form .= "</td></tr>";
2956
		$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Description</td>";
2957
		$form .= "<td class=\"vncellreq\">";
2958
		$form .= "<input type=\"text\" id=\"description\" class=\"formfld unknown\" size=\"50%\" name=\"description\" value=\"";
2959
		$form .= $this->GetDescription();
2960
		$form .= "\">";
2961
		$form .= "<br> <span class=\"vexpl\">";
2962
		$form .= "You may enter a description here ";
2963
		$form .= "for your reference (not parsed).</span>";
2964
		$form .= "</td></tr>";
2965
		$form .= "<tr id=\"sprtable4\" name=\"sprtable4\">";
2966
		$form .= "<td></td>";
2967
                $form .= "<td><div id=\"showadvancedboxspr\">";
2968
                $form .= "<p><input type=\"button\" onClick=\"show_source_port_range()\"";
2969
		$form .= " value=\"Show advanced options\"></input></a>";
2970
                $form .= "</div></td></tr>";
2971
		$form .= "<tr style=\"display:none\" id=\"sprtable\" name=\"sprtable\">";
2972
		$form .= "<td valign=\"top\" class=\"vncellreq\">Weight</td>";
2973
		$form .= "<td valign=\"top\" class=\"vncellreq\">";
2974
		$form .= "<input name=\"weight\" type=\"text\" id=\"weight\" size=\"5\" value=\"";
2975
		$form .= $this->GetWeight() . "\">";
2976
		$form .= "&nbsp;ms<br> <span class=\"vexpl\">Hint: For queues under the same parent"; 
2977
		$form .= "this specifies the share that a queue gets(values range from 1 to 100, you can leave it blank otherwise)</span>";
2978
		$form .= "</td></tr>";
2979
		$form .= "<tr style=\"display:none\" id=\"sprtable1\" name=\"sprtable1\">";
2980
		$form .= "<td valign=\"top\" class=\"vncellreq\">Packet loss rate</td>";
2981
		$form .= "<td valign=\"top\" class=\"vncellreq\">";
2982
		$form .= "<input name=\"plr\" type=\"text\" id=\"plr\" size=\"5\" value=\"";
2983
		$form .= $this->GetPlr() . "\">";
2984
		$form .= "&nbsp;<br> <span class=\"vexpl\">Hint: in most cases, you"; 
2985
        	$form .= "should specify 0 here (or leave the field empty).";
2986
		$form .= "A value of 0.001 means one packet in 1000 gets dropped</span>";
2987
		$form .= "</td></tr>";
2988
		$form .= "<tr style=\"display:none\" id=\"sprtable2\" name=\"sprtable2\">";
2989
		$form .= "<td valign=\"top\" class=\"vncellreq\">Queue Size</td>";
2990
		$form .= "<td class=\"vncellreq\">";
2991
		$form .= "<input type=\"text\" id=\"qlimit\" name=\"qlimit\" value=\"";
2992
		$form .= $this->GetQlimit() . "\">";
2993
		$form .= "&nbsp;slots<br>";
2994
		$form .= "<span class=\"vexpl\">Hint: in most cases, you ";
2995
		$form .= "should leave the field empty. All packets in this pipe are placed into a fixed-size queue first,";
2996
        $form .= "then they are delayed by value specified in the Delay field, and then they ";
2997
		$form .= "are delivered to their destination.</span>";
2998
		$form .= "</td></tr>";
2999
		$form .= "<tr style=\"display:none\" id=\"sprtable5\" name=\"sprtable5\">";
3000
                $form .= "<td valign=\"top\" class=\"vncellreq\">Bucket Size</td>";
3001
                $form .= "<td class=\"vncellreq\">";
3002
                $form .= "<input type=\"text\" id=\"buckets\" name=\"buckets\" value=\"";
3003
                $form .= $this->GetBuckets() . "\">";
3004
                $form .= "&nbsp;slots<br>";
3005
                $form .= "<span class=\"vexpl\">Hint: in most cases, you ";
3006
                $form .= "should leave the field empty. It increases the hash size set.";
3007
                $form .= "</td></tr>";
3008

    
3009
		$form .= "<input type=\"hidden\" id=\"pipe\" name=\"pipe\"";
3010
		$form .= " value=\"" . $this->GetPipe() . "\">";
3011

    
3012
		return $form;
3013
			
3014
	}
3015

    
3016
        function update_dn_data(&$data) { 
3017
		$this->ReadConfig($data);
3018
	}
3019

    
3020
	function wconfig() {
3021
		$cflink =& get_dn_reference_to_me_in_config($this->GetLink());
3022
            	if (!is_array($cflink))
3023
            		$cflink = array();
3024
		$cflink['name'] = $this->GetQname();
3025
		$cflink['number'] = $this->GetNumber();
3026
            	$cflink['qlimit'] = $this->GetQlimit();
3027
            	$cflink['description'] = $this->GetDescription();
3028
		$cflink['weight'] = $this->GetWeight();
3029
		$cflink['enabled'] = $this->GetEnabled();
3030
		$cflink['buckets'] = $this->GetBuckets();
3031
		$cflink['mask'] = $this->GetMask();
3032
	}
3033
}
3034

    
3035

    
3036
/*
3037
 * XXX: TODO Make a class shaper to hide all these function
3038
 * from the global namespace.
3039
 */
3040

    
3041
/* 
3042
 * This is a layer violation but for now there is no way 
3043
 * i can find to properly do this with PHP.
3044
 */
3045
function altq_set_default_queue($interface, $value) {
3046
	global $altq_list_queues;
3047
		
3048
	$altq_tmp =& $altq_list_queues[$interface];
3049
	if ($altq_tmp) {
3050
		if ($value) {
3051
			$altq_tmp->SetDefaultQueuePresent("true");
3052
		}
3053
		else {
3054
			$altq_tmp->SetDefaultQueuePresent("false");
3055
		}
3056
	}
3057
}
3058

    
3059
function altq_get_default_queue($interface) {
3060
	global $altq_list_queues;
3061

    
3062
	$altq_tmp = $altq_list_queues[$interface];
3063
	if ($altq_tmp)  
3064
		return $altq_tmp->GetDefaultQueuePresent(); 
3065
}
3066

    
3067
function altq_check_default_queues() {
3068
	global $altq_list_queues;
3069

    
3070
	$count = 0;
3071
	if (is_array($altq_list_queues)) {
3072
		foreach($altq_list_queues as $altq) {
3073
			if ($altq->GetDefaultQueuePresent())
3074
				$count++;
3075
		}
3076
	}
3077
	else  $count++;;
3078
	
3079
	return 0;
3080
}
3081

    
3082
function &get_unique_queue_list() {
3083
	global $altq_list_queues;
3084
	
3085
	$qlist = array();
3086
	if (is_array($altq_list_queues)) {
3087
		foreach ($altq_list_queues as $altq) {
3088
			$tmplist =& $altq->get_queue_list();
3089
			foreach ($tmplist as $qname => $link)
3090
				$qlist[$qname] = $link;	
3091
		}
3092
	}
3093
	return $qlist;
3094
}
3095

    
3096
function &get_unique_dnqueue_list() {
3097
	global $dummynet_pipe_list;
3098
	
3099
	$qlist = array();
3100
	if (is_array($dummynet_pipe_list)) {
3101
		foreach ($dummynet_pipe_list as $dn) {
3102
			$tmplist =& $dn->get_queue_list();
3103
			foreach ($tmplist as $qname => $link)
3104
				$qlist[$qname] = $link;	
3105
		}
3106
	}
3107
	return $qlist;
3108
}
3109

    
3110
function get_is_ftp_queue($interface, $qname) {
3111
	global $config;
3112

    
3113
	if (isset($config['interfaces'][$interface]['ftpqueue']) &&
3114
		$config['interfaces'][$interface]['ftpqueue'] == $qname)
3115
		return true;
3116
	return false;
3117
}
3118

    
3119
function set_is_ftp_queue($interface, $qname) {
3120
	global $config;
3121

    
3122
	if (!is_array($config['interfaces'][$interface]['ftpqueue']))
3123
		$config['interfaces'][$interface]['ftpqueue'] = array();
3124
	$config['interfaces'][$interface]['ftpqueue'] = $qname;
3125
}
3126

    
3127
function ref_on_altq_queue_list($parent, $qname) {
3128
	if (isset($GLOBALS['queue_list'][$qname]))
3129
		$GLOBALS['queue_list'][$qname]++;
3130
	else
3131
		$GLOBALS['queue_list'][$qname] = 1;
3132

    
3133
	unref_on_altq_queue_list($parent);
3134
}
3135

    
3136
function unref_on_altq_queue_list($qname) {
3137
	$GLOBALS['queue_list'][$qname]--;
3138
	if ($GLOBALS['queue_list'][$qname] <= 1)
3139
		unset($GLOBALS['queue_list'][$qname]);	
3140
}
3141

    
3142
function read_altq_config() {
3143
	global $altq_list_queues, $config;
3144
	$path = array();
3145
	
3146
	$a_int = &$config['shaper']['queue'];
3147

    
3148
	$altq_list_queues = array();
3149
	
3150
	if (!is_array($config['shaper']['queue']))
3151
		return;
3152

    
3153
	foreach ($a_int as $key => $conf) {
3154
				$int = $conf['interface'];
3155
				$root =& new altq_root_queue();
3156
				$root->SetInterface($int);
3157
				$altq_list_queues[$root->GetInterface()] = &$root;
3158
				$root->ReadConfig($conf);
3159
		array_push($path, $key);
3160
		$root->SetLink($path);
3161
		if (is_array($conf['queue'])) {
3162
			foreach ($conf['queue'] as $key1 => $q) {
3163
				array_push($path, $key1);
3164
				/* 
3165
				 * XXX: we compeletely ignore errors here but anyway we must have 
3166
				 *	checked them before so no harm should be come from this.
3167
				 */
3168
				$root->add_queue($root->GetInterface(), $q, &$path, $input_errors);
3169
				array_pop($path);
3170
			} 	
3171
				}
3172
		array_pop($path);
3173
	}
3174
}
3175

    
3176
function read_dummynet_config() {
3177
	global $dummynet_pipe_list, $config;
3178
	$path = array();
3179
	$dnqueuenumber = 1;
3180
	$dnpipenumber = 1;
3181

    
3182
	$a_int = &$config['dnshaper']['queue'];
3183

    
3184
	$dummynet_pipe_list = array();
3185
	
3186
	if (!is_array($config['dnshaper']['queue'])
3187
		|| !count($config['dnshaper']['queue']))
3188
		return;
3189

    
3190
	foreach ($a_int as $key => $conf) {
3191
		if (empty($conf['name']))
3192
			continue; /* XXX: grrrrrr at php */ 
3193
		$root =& new dnpipe_class();
3194
		$root->ReadConfig($conf);
3195
		$root->SetNumber($dnpipenumber);	
3196
		$dummynet_pipe_list[$root->GetQname()] = &$root;
3197
		array_push($path, $key);
3198
		$root->SetLink($path);
3199
		if (is_array($conf['queue'])) {
3200
			foreach ($conf['queue'] as $key1 => $q) {
3201
				array_push($path, $key1);
3202
				/* XXX: We cheat a little here till a better way is found. */
3203
				$q['number'] = $dnqueuenumber;
3204
				/* 
3205
				 * XXX: we compeletely ignore errors here but anyway we must have 
3206
				 *	checked them before so no harm should be come from this.
3207
				 */	
3208
				$root->add_queue($root->GetQname(), $q, &$path, $input_errors);
3209
				array_pop($path);
3210

    
3211
				$dnqueuenumber++;
3212
			} 	
3213
		}
3214
		array_pop($path);
3215
			
3216
		$dnpipenumber++;
3217
	}
3218
}
3219

    
3220
function get_interface_list_to_show() {
3221
	global $altq_list_queues, $config;
3222
	global $shaperIFlist;
3223

    
3224
	$tree = "";
3225
	foreach ($shaperIFlist as $shif => $shDescr) {
3226
		if ($altq_list_queues[$shif]) {
3227
			continue;
3228
		} else  {
3229
			if (!is_altq_capable(get_real_interface($shif)))
3230
				continue;
3231
			$tree .= " <li><a href=\"firewall_shaper.php?interface=".$if."&action=add\">".$shDescr."</a></li>";
3232
		}
3233
	}
3234
	
3235
	return $tree;
3236
}
3237

    
3238
function filter_generate_altq_queues() {
3239
	global $altq_list_queues;
3240
	
3241
	read_altq_config();
3242

    
3243
	$altq_rules = "";
3244
	foreach ($altq_list_queues as $altq) 
3245
		$altq_rules .= $altq->build_rules();
3246

    
3247
	return $altq_rules;
3248
}
3249

    
3250
function filter_generate_dummynet_rules() {
3251
	global $dummynet_pipe_list;
3252
	
3253
	read_dummynet_config();
3254
	
3255
	if (!empty($dummynet_pipe_list)) {
3256
		mwexec("kldload dummynet");
3257
		mwexec("pfctl -F dummynet");
3258
	}
3259

    
3260
	$dn_rules = "";
3261
	foreach ($dummynet_pipe_list as $dn) 
3262
		$dn_rules .= $dn->build_rules();
3263

    
3264
	return $dn_rules;
3265
}
3266

    
3267
function build_iface_without_this_queue($iface, $qname) {
3268
	global $g, $altq_list_queues;
3269

    
3270
	$altq =& $altq_list_queues[$iface];
3271
				if ($altq)
3272
						$scheduler = ": " . $altq->GetScheduler();
3273
	$form = "<tr><td width=\"20%\" >";
3274
	$form .= "<a href=\"firewall_shaper.php?interface" . $iface . "&queue=" . $iface."&action=show\">".$iface.": ".$scheduler."</a>";
3275
		$form .= "</td></tr>";
3276
		$form .= "<tr><td width=\"100%\" class=\"vncellreq\">";
3277
		$form .= "<a href=\"firewall_shaper_queues.php?interface=";
3278
		$form .= $iface . "&queue=". $qname . "&action=add\">";
3279
		$form .= "<img src=\"";
3280
		$form .= "./themes/".$g['theme']."/images/icons/icon_plus.gif\"";
3281
		$form .= " width=\"17\" height=\"17\" border=\"0\" title=\"Clone shaper/queue on this interface\">";
3282
		$form .= " Clone shaper/queue on this interface</a></td></tr>";
3283

    
3284
		return $form;
3285

    
3286
}
3287

    
3288

    
3289
$default_shaper_msg =	"<tr><td align=\"center\" width=\"80%\" >";
3290
$default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
3291
$default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
3292
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
3293
$default_shaper_ms .= " </p></strong></span>";
3294
$default_shaper_msg .= "</td></tr>";
3295

    
3296
$dn_default_shaper_msg =	"<tr><td align=\"center\" width=\"80%\" >";
3297
$dn_default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
3298
$dn_default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
3299
$dn_default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
3300
$dn_default_shaper_ms .= " </p></strong></span>";
3301
$dn_default_shaper_msg .= "</td></tr>";
3302

    
3303

    
3304

    
3305
?>
(28-28/37)