COPS-Client

 view release on metacpan or  search on metacpan

lib/COPS/Client.pm  view on Meta::CPAN

    fully qualified.

    The function takes two parameters the first specifies which IPVx to use,
    the second is the IPVx value.

    An example of use is

        $cops_client->subscriber_set("ipv4","172.20.1.1");

    The subscriber ID is required for 99% of all COPS messages.

=head2 gate_specification_add

    This function builds a gate with the attributes specified. Possible
    attributes are

        Direction      -  This can be 'Upstream' or 'Downstream' only.
                          If specified this overrides Gate_Flags as
                          direction is one bit of the Gate_Flags 
                          parameter.

        Priority       -  This is a value of 0 to 7. If specified this
                          overrides Gate_Class as Priority is 3 bits
                          of that parameter.

        PreEmption     -  This has a value of 0 or 1. This allows this
                          gate to take bandwidth from any other gates
                          already set against this subscriber. If
                          specified this overrides Gate_Class as this is
                          1 bit of that parameter.

        DSCPToSMark    -  This has a value of 0 or 1

        Priority       -  This has a value between 0 and 255 and should
                          determine the priority of the gate.

        Gate_Flags     -  This field is broken down into 2 used bits and
                          6 unused bits.

                          Bit 0    -  Direction. 
                                      0 is Downstream
                                      1 is Upstream
 
                                      If you use the Direction parameter
                                      this is set for you.

                          Bit 1    -  DSCP/TOS Field
                                      0 is enable
                                      1 is overwrite

        GateTOSField    - IP TOS and Precedence value.

        GateTOSMask     - IP TOS Mask settings

        GateClass       - This field is broken down into 8 bits as follows
                       
                          Bit 0-2   - Priority of 0-7
                          Bit 3     - PreEmption bit
                          Bit 4-7   - Configurable but should default 0

        Gate_T1         - Gate T1 timer

        Gate_T2         - Gate T2 timer

        Gate_T3         - Gate T3 timer

        Gate_T4         - Gate T4 timer

    An example of use would be

    $cops_client->gate_specification_add(
        [
        Direction       => 'Downstream',
        DSCPToSMark     => 0,
        Priority        => 0,
        PreEmption      => 0,
        Gate_Flags      => 0,
        Gate_TOSField   => 0,
        Gate_TOSMask    => 0,
        Gate_Class      => 0,
        Gate_T1         => 0,
        Gate_T2         => 0,
        Gate_T3         => 0,
        Gate_T4         => 0
        ]
        );

=head2 classifier_add

    This function adds a classifier to the COPS request being sent and
    supports normal and extended classifiers.

    The function requires two types of parameters depending on the type
    of classifier specified.

    To specify the correct classifier the attribute Classifier_Type
    can be used as follows

        Classifier_Type   -  This should be 'Classifier' or 'Extended'

    Classifier_Type 'Classifier' attributes are as follows

        Classifier_IPProtocolId      - This is a standard IP protocol
                                       number. You can set this to 0
                                       or omit this and a default of 0
                                       will be used.

        Classifier_TOSField          - The TOSField of the IP packets
                                       to match. You can set this to 0
                                       or omit this and a default of 0
                                       will be used.

        Classifier_TOSMask           - The TOSMask of the IP packets 
                                       to match. you can set this to 0
                                       or omit this and a default of 0
                                       will be used.

        Classifier_SourceIP          - This should be set to the source
                                       IP address of the associated flow.
                                       If you have a device attached to
                                       the cable modem such as a PC, then
                                       you should use the IP of that
                                       device, not that of the cable modem.

        Classifier_DestinationIP     - This is the destination IP of the 
                                       flow. It can be a wildcard of 0.
                                       If you omit this then a default 0

lib/COPS/Client.pm  view on Meta::CPAN

        );

    This sets up the Envelope to be authorized, reserved and committed. It contains a Service
    Class Name (this should be configured on the CMTS already) and it has been named as
    S_down. If the specified ServiceClassName is incorrect or does not correspond to the
    direction specified an error will be returned.

=head2 rks_set

    This function add a Reporting server to the COPS request. You can have a primary and
    secondary Reporting server and events, such as volume quota reached, time reached should
    be report to the Reporting server configured. All Reporting server messages are via 
    the RADIUS protocol. This rks_set only supports IPV4 addressing.

    As part of a RKS request you can also specify unique indentifiers that will be sent in
    the Reporting request for each specific gate created. The Gate ID is not sent in the 
    reporting request so some external management system will need to track these.

    The variables you can set in an RKS configuration are as follows

    PRKS_IPAddress                 - This is the PRIMARY (PRKS) reporting server IP address.
                                     It should be specified as an IP, hostnames are not
                                     supported and only IPV4 is available.

    PRKS_Port                      - This is the Port that reporting messages are sent to.
                                     The protocol used is RADIUS so the standard 1813 port
                                     should be used if a default RADIUS server configuration
                                     is to be used.

    PRKS_Flags                     - Ignore, further work is required, however if you
                                     understand this usage it is available to be set.

    SRKS_IPAddress                 - This is the SECONDARY (SRKS) reporting server IP address.
                                     This is ONLY used if the primary is considered down.
                                     It should be specified as an IP, hostnames are not
                                     supported and only IPV4 is available.

    SRKS_Port                      - This is the Port that reporting messages are sent to
                                     for the SECONDARY reporting server.

    SRKS_Flags                     - Ignore, further work is required, however if you
                                     understand this usage it is available to be set.

    
    Billing Correlation Identification

    BCID_TimeStamp                 - This is a 32bit number and EPOCH is a good use here.
                                  
    BCID_ElementID                 - This is an eight (8) character entry and should be
                                     alphanumeric only to be supported by all vendors.

    BCID_TimeZone                  - This is an eight(8) character entry and specifies
                                     the timezone of the entry. 

    BCID_EventCounter              - This is a 32bit number and can be anything within that
                                     range. This could be an auto-increment in a table, so
                                     allowing GateID to be linked back later.

    An example of use would be

        my $timer=time();

        $cops_client->rks_set (
                        [
                        PRKS_IPAddress          => '192.168.50.2',
                        PRKS_Port               => 2000,
                        PRKS_Flags              => 0,
                        SRKS_IPAddress          => 0,
                        SRKS_Port               => 0,
                        SRKS_Flags              => 0,
                        BCID_TimeStamp          => $timer,
                        BCID_ElementID          => '99999999',
                        BCID_TimeZone           => '00000000',
                        BCID_EventCounter       => 12347890
                        ]
                        );

    You can omit fields which are not used and they will default to 0, but for completeness
    are included above.
 
=head2 decode_radius_attribute

    This function takes the output from FreeRadius 2.1.9 and expands it where possible. The
    supported attributes are

         CableLabs-Event-Message
         CableLabs-QoS-Descriptor

    When called this function returns the converted attribute into a hash of the attributes
    found and decoded.

    An example of use would be

    my %return_data;

    $cops_client->decode_radius_attribute("CableLabs-Event-Message",
        "
        0x00034c163b873939393939393939303030303030303000bc69f2000700022020203232323200312b3030303030300000002b32303130303631343135313233382e3032330000000080000400",
        \%return_data);

    Note the 0x is required at the beginning so validity checking will pass.

    The %return_data has should then contain the following keys with values.

        EventMessageVersionID        -  3
        TimeZone                     -  1+000000
        Status                       -  0
        AttributeCount               -  4
        SequenceNumber               -  43
        BCID_TimeZone                -  00000000
        EventObject                  -  0
        ElementType                  -  2
        EventMessageType             -  7
        BCID_Timestamp               -  1276525447
        BCID_ElementID               -  99999999
        BCID_EventCounter            -  12347890
        EventMessageTypeName         -  QoS_Reserve
        Priority                     -  128
        ElementID                    -  '   2222'
        EventTime                    -  20121019163303.51

=head2 volume_set

    This functions adds a volume limit to the gate being sent. You should be aware the CMTS
    may not stop traffic flowing through the gate when the limit is reached, implementation
    dependent, however should send a RKS notification.

    This function just takes the Volume in the number of bytes, 64 bit number.

    An example of use would be

lib/COPS/Client.pm  view on Meta::CPAN

		"Insufficient resources",
		"Unknown Gate ID",
		"Unknown",
		"Unknown",
		"Unknown",
		"Missing Required Object",
		"Invalid Object",
		"Volume based usage limit exceeded",
		"Time based usage limit exceeded", 
		"Session Class Limit Exceeded",
		"Undefined Service Class Name",
		"Incompatible Envelope",
		"Invalid subscriber identifier",
		"Unauthorized AMID",
		"Number of Classifiers not supported",
		"Policy Exception",
		"Invalid field value in object",
		"Transport Error",
		"Unknown gate command",
		"DOCSIS 1.0 CM",
		"Number of SIDs exceeded in CM",
		"Number of SIDs exceeded in CMTS",
		"Unauthorized PSID",
		"No state for PDPD",
		"Unsupport Sync Type",
		"State data incomplete",
		);

if (!$errors[$error])
	{ return "Other, unspecified error"; }
return $errors[$error];
}

sub gate_states
{
my ( $self ) = shift;
my ( $state_no ) = shift;
my ( @states ) =
		(
		"",
		"Idle/Closed",
		"Auhorized",
		"Reserved",
		"Committed",
		"Committed Recovery"
		);
if ( !$states[$state_no] )
	{ return "Unknown"; }
return $states[$state_no];
}

sub gate_reasons
{
my ( $self ) = shift;
my ( $reason ) = shift;
my ( @reasons ) = 
		(
		"",
		"Close Initiated by CMTS because of reservation reassignment",
		"Close Initiated by CMTS because of lack of DOCSIS responses",
		"Close Initiated by CMTS because of timer T1 expiry",
		"Close Initiated by CMTS because of timer T2 expiry",
		"Inactivity timer (T3) expired",
		"Close Initiated by CMTS because of a lack of reservation maintenance",
		"Gate state unchanged, but volume limit reached",
		"Close Initiated by CMTS because of timer T4 expiry",
		"Gate State unchanged, but timer T2 expiry caused reservation reduction",
		"Gate State unchanged, but time limit reached",
		"Close Initiated by PS or CMTS, volume limit reached",
		"Close Initiated by PS or CMTS, time limit reached",
		"Close Initiated by CMTS, other"
		);

if ( !$reasons[$reason] )
	{
	return "Other";
	}
return $reasons[$reason];
}

sub gate_array
{
my ( $self ) = shift;
my ( @gate_headers ) =
		(
		[
		"Gate_Flags",
		"Gate_TOSField",
		"Gate_TOSMask",
		"Gate_Class",
		"Gate_T1",
		"Gate_T2",
		"Gate_T3",
		"Gate_T4"
		]
		);
return \$gate_headers[0];
}

sub rks_array
{
my ( $self ) = shift;
my ( @rks_headers ) = 
		(
		[
		"PRKS_IPAddress",
		"PRKS_Port",
		"Reserved",
		"Reserved",
		"SRKS_IPAddress",
		"SRKS_Port",
		"Reserved",
		"Reserved",
		"BCID_TimeStamp",
		"BCID_ElementID",
		"BCID_TimeZone",
		"BCID_EventCounter"
		]
		);
return \$rks_headers[0];
}

sub rks_set
{
my ( $self ) = shift;
my ( $data ) = shift;
my ( %test );

lib/COPS/Client.pm  view on Meta::CPAN

{
my ( $self ) = shift;
my ( $data ) = shift;
my ( $packed ) = "";
my ( $done_pack ) =0;

$packed = pack("CC",8,1);
my ( $rks_headers ) = $self->rks_array();
$packed .= $self->general_pack ( $data, $rks_headers );
my ( $length ) = pack("n",(length($packed)+2));
return $length.$packed;
}

sub rks_get
{
my ( $self ) = shift;
if ( $self->{_GLOBAL}{'RKS_Encoded'} )
        {
        return $self->{_GLOBAL}{'RKS_Encoded'};
        }
return "";
}


sub opaque_clear
{
my ( $self ) = shift;
$self->{_GLOBAL}{'OpaqueData'}="";
return 1;
}

sub opaque_set
{
my ( $self ) = shift;
my ( $data ) = shift;
my ( %test );
my ( $encoded ) = "";
while (my($field, $val) = splice(@{$data}, 0, 2))
	{ $test{$field}= $val }
if ( $test{'OpaqueData'} )
	{
	$encoded = pack("CC",11,1);
	$encoded.= $self->align_string( $test{'OpaqueData'} );
	my ( $length ) = pack("n",(length($encoded)+2));
	$encoded= $length.$encoded;
	}
$self->{_GLOBAL}{'OpaqueData'} = $encoded;
return 1;
}

sub timebase_set
{
my ( $self ) = shift;
my ( $data ) = shift;
if ( $self->{_GLOBAL}{'DEBUG'}> 4 )
	{
	print "Time set to '".$data."'\n";
	}
if ( $data > 0 )
	{
	my $timer_encode = $self->encode_time_limit( $data );
	$self->{_GLOBAL}{'TimeLimit'} = $timer_encode;
	}
return 1;
}

sub timebase_clear
{
my ( $self ) = shift;
$self->{_GLOBAL}{'TimeLimit'} = "";
return 1;
}

sub volume_set
{
my ( $self ) = shift;
my ( $data ) = shift;
if ( $data>0 )
	{ 
	my $timer_encode = $self->encode_byte_limit( $data ); 
	$self->{_GLOBAL}{'VolumeLimit'} = $timer_encode;
	}
return 1;
}

sub volume_clear
{
my ( $self ) = shift;
$self->{_GLOBAL}{'VolumeLimit'} = "";
return 1;
}

sub opaque_get
{
my ( $self ) = shift;
if ( $self->{_GLOBAL}{'OpaqueData'} )
	{
	return $self->{_GLOBAL}{'OpaqueData'};
	}
return "";
}

sub volume_get
{
my ( $self ) = shift;
if ( length($self->{_GLOBAL}{'VolumeLimit'})>0 )
	{
	return $self->{_GLOBAL}{'VolumeLimit'};
	}
return "";
}

sub timebase_get
{
my ( $self ) = shift;
if ( length($self->{_GLOBAL}{'TimeLimit'})>0 )
	{
	return $self->{_GLOBAL}{'TimeLimit'};
	}
return "";
}

sub gate_specification_add
{
my ( $self ) = shift;
my ( $data ) = shift;
my ( %test );
while (my($field, $val) = splice(@{$data}, 0, 2))
                { 
		$test{$field}= $val;
		}
my ( $priority ) =0;
my ( $preemption ) =0;
foreach my $field ( keys %test )
		{
		my $val = $test{$field};
		print "Gate key is '$field' value is '$val'\n" if $self->{_GLOBAL}{'DEBUG'}>0;
		if ( $field=~/^direction$/i )
			{
			if (!$test{'Gate_Flags'}) { $test{'Gate_Flags'}=0; }
			$test{'Gate_Flags'}=$test{'Gate_Flags'} & 0xFE;



( run in 0.537 second using v1.01-cache-2.11-cpan-39bf76dae61 )