Acme-RFC4824
view release on metacpan or search on metacpan
lib/Acme/RFC4824.pm view on Meta::CPAN
my $frame = $arg_ref->{FRAME};
if (! defined $frame) {
croak "You need to pass a frame to be decoded.";
}
my $last_frame_undo = rindex $frame, 'T';
if ($last_frame_undo > 0) {
# if a FUN was found, take everything to the right to be the
# new frame.
$frame = 'Q' . substr($frame, $last_frame_undo + 2);
}
while ($frame =~ m{ (.*) [^S]S (.*) }xms) {
# delete the signal before a 'S' (SUN, signal undo)
$frame = $1 . $2;
}
$frame =~ s/[U-Y]//g; # ignore ACK, KAL, NAK, RTR and RTT signals
my ($header, $payload, $checksum) =
($frame =~ m{\A Q([A-E][A-B][A-P]{2}) ([A-P]+) ([A-P]{4})R \z}xms);
if (! defined $header || ! defined $payload || ! defined $checksum) {
croak "Invalid frame format.";
}
return $self->__pack($payload);
}
sub __pack {
my $self = shift;
my $frame = shift;
# convert from ASCII to hex
$frame =~ tr/A-J/0-9/;
$frame =~ tr/K-P/a-f/;
return pack('H*', $frame);
}
sub __unpack {
my $self = shift;
my $data = shift;
# unpack
my $result = unpack('H*', $data);
$result =~ tr/0-9/A-J/;
$result =~ tr/a-f/K-P/;
return $result;
}
sub encode {
my $self = shift;
my $arg_ref = shift;
my $sfs_frame = 'Q'; # Frame Start FST
# type is ASCII or ASCII-ART
my $type = 'ASCII';
if (defined $arg_ref->{TYPE}) {
$type = $arg_ref->{TYPE};
}
if ($type ne 'ASCII' && $type ne 'ASCII art') {
croak "Invalid output type";
}
my $packet = $arg_ref->{PACKET};
if (! defined $packet || ! length($packet)) {
croak "You need to pass an IP packet";
}
my $checksum = 0;
if (defined $arg_ref->{CHECKSUM}) {
$checksum = $arg_ref->{CHECKSUM};
};
# TODO - implement CRC 16 support
if ($checksum == 1) {
croak "CRC 16 support not implemented (yet).";
}
elsif ($checksum > 1) {
croak "Invalid checksum type";
}
my $framesize = $self->{default_framesize};
if (exists $arg_ref->{FRAMESIZE}) {
$framesize = $arg_ref->{FRAMESIZE};
}
# TODO - implement fragmenting
# note: honor DF bit in IP packets
if (length($packet) > $framesize) {
croak "Fragmenting not implemented (yet).";
}
# TODO - implement support for gzipped frames
my $gzip = $arg_ref->{GZIP};
if ($gzip) {
croak "GZIP support not implemented (yet).";
}
my $packet_ascii = $self->__unpack($packet);
if (substr($packet_ascii, 0, 1) eq 'E') { # E=4: IPv4
$sfs_frame .= 'B';
}
elsif (substr($packet_ascii, 0, 1) eq 'G') { # G=6: IPv6
$sfs_frame .= 'C';
}
else {
croak "Invalid IP version";
}
$sfs_frame .= 'A'; # Checksum Type: none
$sfs_frame .= 'AA'; # Frame number 0x00
$sfs_frame .= $packet_ascii;
$sfs_frame .= 'AAAA'; # No checksum, so we just set it zeros
$sfs_frame .= 'R'; # Frame End, FEN
if ($type eq 'ASCII') {
return $sfs_frame;
}
else { # ASCII-ART
my @sfss_ascii_art_frames = ();
for (my $i = 0; $i < length($sfs_frame); $i++) {
my $char = substr($sfs_frame, $i, 1);
my $aa_repr = $self->ascii2art_map->{$char};
if (! defined $aa_repr) {
die "No ASCII-Art representation for '$char'";
}
push @sfss_ascii_art_frames, $aa_repr;
}
if (wantarray) {
return @sfss_ascii_art_frames;
}
else {
return join "\n", @sfss_ascii_art_frames;
}
}
}
1;
__END__
=head1 NAME
Acme::RFC4824 - Internet Protocol over Semaphore Flag Signaling System (SFSS)
=head1 VERSION
Version 0.01
=head1 SYNOPSIS
This module is used to help you implement RFC 4824 - The Transmission
of IP Datagrams over the Semaphore Flag Signaling System (SFSS).
It can be used to convert IP datagrams to SFS frames and the other
way round. Furthemore, it can be used to display an ASCII art representation
of the SFS frame.
use Acme::RFC4824;
my $sfss = Acme::RFC4824->new();
# get IP datagram from somewhere (for example Net::Pcap)
# print a representation of the SFS frame
print $sfss->encode({
TYPE => 'ASCII art',
PACKET => $datagram,
});
# get an ASCII representation of the SFS frame
my $sfs_frame = $sfss->encode({
TYPE => 'ASCII',
PACKET => $datagram,
});
# get an SFS frame from somewhere
# (for example from someone signaling you)
# get an IP datagram from the frame
my $datagram = $sfss->decode({
FRAME => $frame,
});
=head1 EXPORT
( run in 0.617 second using v1.01-cache-2.11-cpan-4ef0a570458 )