English 中文(简体)
UDP 佩尔卢姆职务
原标题:UDP Checksum Function in Perl
  • 时间:2017-09-12 16:18:49
  •  标签:
  • c
  • perl

我在Perl搜索了计算民主力量头盔所需的大量职能。

I find this function in C: http://www.netfor2.com/udpsum.htm But i don t know how to use it and i try to convert it to Perl but not managed

这样做是为了:

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;
}

请帮助我。

最佳回答
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."",  # 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));

2. 核实UDP的包裹检查表

udp_checksum($packed_src_addr, $packed_dst_addr, $udp_packet)
    and die("Invalid checksum
");

例:

#!/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 "

UDP Checksum: $checksum

";
}

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."",  # Extra byte ignored if length($udp_packet) is even.
        ),
    );

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

    return ~$sum & 0xFFFF;
}
问题回答

我在计算 per检查时使用:

my $chk = ~((unpack "%32S*", $pkt) % 65535)

之后将它装在包装上:

substr $msg, 12 + 16, 2, pack "S", $chk;

防止母婴传播的检查工作不同,表达方式是:

my $chk = (~unpack "%32S*", $dstip) % 65535




相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签