Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Perl中的UDP校验和函数_C_Perl - Fatal编程技术网

C Perl中的UDP校验和函数

C Perl中的UDP校验和函数,c,perl,C,Perl,我在Perl中搜索了很多计算UDP报头校验和所需的函数 我在C中找到这个函数: 但我不知道如何使用它,我尝试将其转换为Perl,但没有进行管理 这就是我所尝试的: sub udp_checksum(my $len_udp, my @src_addr, my @dest_addr, my $padding, my @buff) { my $proto_udp = 17; my $padd = 0; my $word16; my $sum; # Find o

我在Perl中搜索了很多计算UDP报头校验和所需的函数

我在C中找到这个函数: 但我不知道如何使用它,我尝试将其转换为Perl,但没有进行管理

这就是我所尝试的:

sub udp_checksum(my $len_udp, my @src_addr, my @dest_addr, my $padding, my @buff)
{
    my $proto_udp = 17;
    my $padd = 0;
    my $word16;
    my $sum;

    # Find out if the length of data is even or odd number. If odd,
    # add a padding byte = 0 at the end of packet
    if ($padding&1==1){
        $padd = 1;
        $buff[$len_udp] = 0;
    }

    # initialize sum to zero
    $sum = 0;

    # make 16 bit words out of every two adjacent 8 bit words and 
    # calculate the sum of all 16 bit words
    for (my $i = 0; $i < $len_udp + $padd; $i = $i + 2){
        $word16 =(($buff[i] << 8) & 0xFF00) + ($buff[i+1] & 0xFF);
        $sum = $sum + $word16;
    }

    # add the UDP pseudo header which contains the IP source and destinationn addresses
    for (my $i = 0; $i < 4; $i = $i + 2){
        $word16 =(($src_addr[i] << 8) & 0xFF00) + ($src_addr[i+1] & 0xFF);
        $sum = $sum + $word16;
    }

    for (my $i = 0; $i < 4; $i = $i + 2){
        $word16 =(($dest_addr[i] << 8) & 0xFF00) + ($dest_addr[i+1] & 0xFF);
        $sum = $sum + $word16;
    }

    # the protocol number and the length of the UDP packet
    $sum = $sum + $prot_udp + $len_udp;

    # keep only the last 16 bits of the 32 bit calculated sum and add the carries
        while ($sum >> 16){
            $sum = ($sum & 0xFFFF) + ($sum >> 16);
        }

    # Take the one's complement of sum
    $sum = ~$sum;

    return $sum;
}
sub-udp\u校验和(my$len\u udp,my@src\u addr,my@dest\u addr,my$padding,my@buff)
{
我的$proto_udp=17;
我的$padd=0;
我的$word16;
我的$sum;
#找出数据的长度是偶数还是奇数。如果是奇数,
#在数据包末尾添加一个填充字节=0
如果($padding&1==1){
$padd=1;
$buff[$len_udp]=0;
}
#将和初始化为零
$sum=0;
#每两个相邻的8位字组成16位字,然后
#计算所有16位字的总和
对于(我的$i=0;$i<$len_udp+$padd;$i=$i+2){
$word16=($buff[i]>16);
}
#取一之和的补数
$sum=~$sum;
返回$sum;
}
请帮帮我

use List::Util qw( sum );
use Socket     qw( IPPROTO_UDP );

sub udp_checksum {
    my $packed_src_addr = shift;  # As 4-char string, e.g. as returned by inet_aton.
    my $packed_dst_addr = shift;  # As 4-char string, e.g. as returned by inet_aton.
    my $udp_packet      = shift;  # UDP header and data as a string.

    my $sum = sum(
        IPPROTO_UDP,
        length($udp_packet),
        map({ unpack('n*', $_) }
            $packed_src_addr,
            $packed_dst_addr,
            $udp_packet."\0",  # Extra byte ignored if length($udp_packet) is even.
        ),
    );

    while (my $hi = $sum >> 16) {
        $sum = ($sum & 0xFFFF) + $hi;
    }

    return ~$sum & 0xFFFF;
}
要构建UDP数据包

my $udp_packet = pack('nnnna*', $src_port, $dst_port, 8+length($body), 0, $body);
my $checksum = udp_checksum($packed_src_addr, $packed_dst_addr, $udp_packet);
substr($udp_packet, 6, 2, pack('n', $checksum));
要验证UDP数据包的校验和

udp_checksum($packed_src_addr, $packed_dst_addr, $udp_packet)
    and die("Invalid checksum\n");
例如:

#!/usr/bin/perl

use strict;
use Socket;
use warnings;
use List::Util qw(sum);
use Socket     qw(IPPROTO_UDP);
use Socket     qw(inet_aton);

main();

sub main {
    my $src_port = 27005;
    my $dst_port = 27015;
    my $body = pack("H*", "92380000621f008063d5179000927df3a2e09bf319a66bf300c239aa9393d8eaa244119a");
    my $packed_src_addr = inet_aton("156.215.205.76");
    my $packed_dst_addr = inet_aton("31.186.251.163");

    my $udp_packet = pack('nnnna*', $src_port, $dst_port, 8+length($body), 0, $body);
    my $checksum = udp_checksum($packed_src_addr, $packed_dst_addr, $udp_packet);

    print "\n\nUDP Checksum: $checksum\n\n";
}

sub udp_checksum {
    my $packed_src_addr = shift;  # As 4-char string, e.g. as returned by inet_aton.
     my $packed_dst_addr = shift;  # As 4-char string, e.g. as returned by inet_aton.
    my $udp_packet      = shift;  # UDP header and data as a string.

    my $sum = sum(
    IPPROTO_UDP,
    length($udp_packet),
    map({ unpack('n*', $_) }
        $packed_src_addr,
        $packed_dst_addr,
        $udp_packet."\0",  # Extra byte ignored if length($udp_packet) is even.
        ),
    );

    while (my $hi = $sum >> 16) {
        $sum = ($sum & 0xFFFF) + $hi;
    }

    return ~$sum & 0xFFFF;
}

马上,
sub-udp_校验和(我的$len_udp,我的@src_addr,我的@dest_addr,我的$padding,我的@buff){…}
不是Perl。这可能是唯一的问题。
return$sum;
应该是
return$sum&0xFFFF;
提示:
$sum=$sum+$word16;
可以写成
$sum+=$word16;
已经使用了~而不是使用了&mask。关于+=很好的建议,我现在没有检查样式。我正在尝试转换它s、 那么,我如何创建一个子函数并像在C中那样向其传递参数呢?您能否告诉我如何使用此函数?Re“havey used~”而不是使用&mask,这没有意义。
return$sum;
应该是
return$sum&0xFFFF;
.Hmm,很好地解释了你所说的4字符是什么意思?例如:源ip:94.122.166.249和dest:5.196.159.54那么我如何编写它们?
使用套接字qw(inet\u aton);my$addr=inet\u aton(“94.122.166.249”)
也接受域名。或者,
我的$addr=pack('C4',split(/\./,“94.122.166.249”);
和udp头是src-port,dest-port,udp-length,这些都是整数,那么我如何把它们加在一起?数据是十六进制的,如果你能给我举个例子吗?我使用wireshark,所以我说这是
我的$udp\u-packet=pack=pack('nnnna*',$src_port,$dst_port,8+长度($body),0,$body);
和如下值:
$src_port=27005
$dst_port=27015$body=“\xf6\x12\x00\x00\x5d\x12\x700\x80\x63\x33\x10\xf4\xf6\x50\xbd\xbd\xbd\x3a\x84\xb1\xb2\xb2\x74”