网络通信 频道

用PERL实现一个简单的NIDS(3)

sub decode {
my $class = shift;
my($data) = @_;
my $self = {};

my $cmdhead = 0;
my $cmdtail = 0;
my @parts = ();
my $cmdcount = 0;
my $returnindex = 0;
my $data_len = length($data);

# 如果数据长度过短则不处理
if ($data_len >= 4) {
# 一个包里的FTP命令个数
$self->{cmdcount} = 0;
# 搜索回车,之前认为是一个命令行,需要注意的是一个包里可能包含多个FTP命令
while ( (($returnindex = index ($data,"\x0a",$cmdhead)) >=0) || (($returnindex < 0) && (($data_len - $cmdhead) >= 4))) {
# 调整一个命令行串尾指针
if ($returnindex < 0) {
$cmdtail = $data_len -1;
} else {
$cmdtail = $returnindex;
}

if ((my $cmdlen = ($cmdtail - $cmdhead + 1)) >= 4) {
# 取出命令行串
my $cmdline = substr($data,$cmdhead,$cmdlen);
# 从命令行里拆分出命令名和它的参数串
if (splitcmd($cmdline,\@parts)) {
$self->{cmdcount}++;
my $cmdindex = "cmd"."$self->{cmdcount}";
my $paraindex = "para"."$self->{cmdcount}";
# 记录到要返回到主程序的对象
$self->{$cmdindex} = $parts[0];
$self->{$paraindex} = $parts[1];
}
}
# 调整命令行串头指针
$cmdhead = $cmdtail + 1;
}

# 如果命令个数大于0,则说明解码是有效的
if ($self->{cmdcount} == 0) {
$self->{valid} = 0;
} else {
$self->{valid} = 1;
}

} else {
$self->{valid} = 0;
}

# 返回对象

bless($self, $class);
return $self;
}


sub splitcmd {
my ($cmdline,$parts) = @_;

# 去除行尾的回车
chomp($cmdline);
# 用正则表达式抽取出命令名字和参数,既然效率不是考虑的主要问题就“毫无顾忌”地使用正则表达式,因为方便
if ($cmdline =~ m/^\s*([a-zA-Z]{3,4})\s+(.*)/) {
my $valid_cmd = 0;
# 检查抽出来的命令名字是否是一个已知的合法FTP命令
for (my $i=0;$i<@ftp_cmds;$i++) {
if ($ftp_cmds[$i] eq uc($1)) {
$valid_cmd = 1;
last;
}
}
# 如果是合法的命令则返回给调用函数
if ($valid_cmd) {
${$parts}[0] = $1;
${$parts}[1] = $2;
return 1;
} else {
return 0;
}

} else {
return 0;
}
}

#
# Module initialisation
#

1;

# autoloaded methods go after the END token (&& pod) below

__END__

 

文章转载地址:http://www.cnpaf.net/Class/hack/05121820344993970497.htm

0
相关文章