<?php ## docsis.class
## version 0.4
## Matthew Hoskins 10/21/2001
## This PHP class provides a mechanism to generate binary compatible docsis 1.0 configuration files.
## These files can then be loaded onto a tftp server to be downloaded by cable modems. Not all
## DOCSIS settings are present in this class. I will be adding them as time permits. Currently,
## the following settings are available: maximum CPEs, SNMP variables (not SNMP write-access),
## Class of Service definitions (up to 16 in one config), and the net access bit. Here is a sample
## program that generates a file named /tmp/docsisfile.cm:
## require_once("docsis.class");
## $doc = new docsis;
## $doc->set_net_access(1);
## $doc->set_max_cpe(2);
## $doc->add_cos( "myClass", array("maxdown" => 512000,
## "maxup" => 256000 )
## );
## $doc->encode("/tmp/docsisfile.cm", NULL);
## The functions available this class are documented below:
## set_net_access( boolean $bit )
## -----------------------------
## This option is required according to DOCSIS. When initializing this class, this bit is set to 1.
## You can change this setting by calling this function. If bit is 1, the Cable Modem will be granted
## access to the network. If bit is 0, the Cable Modem will range indefinately.
## set_max_cpe( int $number )
## --------------------------
## Sets the maximum number of customer premise equipment devices that can be active behind the Cable
## Modem at a time. This option is optional.
## add_cos ( string $classname, array $classoptions )
## --------------------------------------------------
## Adds a class of service profile. Up to 16 profiles can exist in one config file. Each profile is
## distinguished by $classname. $classoptions is an associative array which define the characteristics
## of the profile. The following keys are valid:
##
## Key Name Definition
## -------- ----------
## maxdown Maximum Downstream speed CM is capable of. (in bits per second eg: 512000)
## maxup Maximum Upstream speed CM is capable of. (in bits per second eg: 256000)
## priority The priority the traffic is given in routing decision.
## Possible range: 0 best - 7 worst.
## minup The minimum Upstream bandwidth you are garaunteed (in bits per second eg 256000)
## maxburst The maximum amount of bandwidth that can be bursted through your cable modem
## in bits per second eg 1024000
## BPI Enable Baseline Privacy. boolean 1 enable, 0 disable. (NOTE: BPI is always set
## to 0, no matter the value of this setting. BPI will be implemented in the next
## release.)
##
## Note: Not setting one of these keys, will result in that setting being set to 0 in the config file.
## del_cos ( string $classname )
## -----------------------------
## Deletes the class of service profile associated with $classname
## add_snmp ( string $snmpname, array $snmpParam )
## -----------------------------------------------------
## To use this function, you need to require the BER class definition file. It should have been included with
## this distribution.
## Adds an snmp variable to the file. Currently two types are supported: INTEGER and IPADDRESS.
## Example: $doc->add_snmp("TEST OID", array( oid => "1.2.3.4.5.6",
## type => "INTEGER",
## value => 1023)
## del_snmp ( string $snmpname )
## -----------------------------
## Deletes the snmp variable associated with $snmpname
## encode( string $filename )
## --------------------------
## Writes the file out in binary to file $filename. Sets the variable $cmfile to the binary contents of the file.
## Returns the number of bytes written.
#
class docsis {
var $cos = array();
var $snmpVars = array();
var $net;
var $maxcpe;
var $cmfile;
var $err;
function docsis() {
$this->net = pack("H2H2H2", "03", "01", "01");
}
function set_net_access($bit) {
$this->net = pack("H2H2H2", "03", "01", str_pad(dechex($bit), 2, "0", STR_PAD_LEFT));
}
function set_max_cpe($cpe) {
$this->maxcpe = pack("H2H2H2", "12", "01", str_pad(dechex($cpe), 2, "0", STR_PAD_LEFT));
}
function add_cos ( $name, $param) {
if (count($this->cos) > 16) {
$this->err = "DOCSIS 1.0 standard limits number of 'Class of Service' definitions to 16.";
return(NULL);
}
$this->cos[$name] = $this->cos[$name].pack("H2H2H2",
str_pad(dechex("1"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("1"), 2, "0", STR_PAD_LEFT),
str_pad(dechex(count($this->cos) + 1), 2, "0", STR_PAD_LEFT));
$this->cos[$name] = $this->cos[$name].pack("H2H2H8",
str_pad(dechex("2"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("4"), 2, "0", STR_PAD_LEFT),
str_pad(dechex($param["maxdown"]), 8, "0", STR_PAD_LEFT));
$this->cos[$name] = $this->cos[$name].pack("H2H2H8",
str_pad(dechex("3"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("4"), 2, "0", STR_PAD_LEFT),
str_pad(dechex($param["maxup"]), 8, "0", STR_PAD_LEFT));
$this->cos[$name] = $this->cos[$name].pack("H2H2H2",
str_pad(dechex("4"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("1"), 2, "0", STR_PAD_LEFT),
str_pad(dechex($param["priority"]), 2, "0", STR_PAD_LEFT));
$this->cos[$name] = $this->cos[$name].pack("H2H2H8",
str_pad(dechex("5"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("4"), 2, "0", STR_PAD_LEFT),
str_pad(dechex($param["minup"]), 8, "0", STR_PAD_LEFT));
$this->cos[$name] = $this->cos[$name].pack("H2H2H4",
str_pad(dechex("6"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("2"), 2, "0", STR_PAD_LEFT),
str_pad(dechex($param["maxburst"]), 4, "0", STR_PAD_LEFT));
$this->cos[$name] = $this->cos[$name].pack("H2H2H2",
str_pad(dechex("7"), 2, "0", STR_PAD_LEFT),
str_pad(dechex("1"), 2, "0", STR_PAD_LEFT),
str_pad(dechex(0), 2, "0", STR_PAD_LEFT));
$this->cos[$name] = pack("H2H2", "04",
str_pad(dechex(strlen($this->cos[$name])), 2, "0", STR_PAD_LEFT)).
$this->cos[$name];
return (count($this->cos));
}
function del_cos ($name) {
unset($this->cos[$name]);
}
function add_snmp ($name, $param) {
$encoder = new BER;
$varbind = $encoder->encode_snmp($param["oid"], $param["type"], $param["value"]);
$length = str_pad(dechex(strlen($varbind)), 2, "0", STR_PAD_LEFT);
$this->snmpVars[$name] = pack("H2H2H".(strlen($varbind) / 2), "0B", $length, $varbind);
}
function del_snmp ($name) {
unset($this->snmpVars[$name]);
}
function encode($filename, $authentication) {
if (count($this->cos) >= 1) {
foreach ($this->cos as $ClassOfService) {
$ClassOfServices = $ClassOfServices.$ClassOfService;
}
} else {
$this->err = "No Class of Services defined.";
return (NULL);
}
if (count($this->snmpVars) >= 1) {
foreach ($this->snmpVars as $snmp) {
$snmpVarBinds = $snmpVarBinds.$snmp;
}
}
$binary = $this->net.$ClassOfServices.$snmpVarBinds.$this->maxcpe;
$cm_mic = pack("H2H2H32", "06", "10", md5($binary));
$cmts_mic = pack("H2H2H32", "07", "10", bin2hex(mhash(MHASH_MD5, $this->net.$ClassOfServices.$cm_mic.$this->maxcpe, $authentication)));
$binary = $binary.$cm_mic.$cmts_mic.pack("H2", "FF");
if (strlen($binary) % 4) {
$padlen = 4 - (strlen($binary) % 4);
$binary = $binary.pack("H".($padlen * 2), str_pad("0", ($padlen * 2), "0", STR_PAD_RIGHT));
}
$this->cmfile = $binary;
$fh = fopen($filename, "w+");
fwrite($fh, $binary);
fclose($fh);
return(strlen($binary));
}
}
?>
?>
|
|