willambender has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks. I'm having a bit of a problem with Net::RawIP and getting the proper ip/udp checksum to generate correctly. According to the documentation, setting "check => 0" would result in the checksum being calculated automatically. I've been trying different combinations of options (setting len, ttl, tos, etc..) with no luck. What am i missing ? Thanks for any/all help.
- Will.

use Net::RawIP; my $packet = new Net::RawIP({udp=>{check => 0}}); $packet->set({ ip => { saddr => "192.168.10.10", daddr => "192.168.10.20" }, udp => { source => 6544, dest => 514, data => 'test123' } }); $packet->send;

tcpdump shows:

13:24:07.572481 IP (tos 0x10, ttl 55, id 45453, offset 0, flags [DF], +proto UDP (17), length 35) 192.168.10.10.6544 > 192.168.10.20.514: [bad udp cksum 8!] [|syslo +g]
Tested on FreeBSD 9.1 and Net-RawIP-0.25,1

Replies are listed 'Best First'.
Re: Net::RawIP - invalid checksum ?
by VinsWorldcom (Prior) on Dec 07, 2013 at 02:04 UTC

    Not sure what you're trying to do - other than create custom UDP packets. If that's the only requirement, you can try the Perl Packet Crafter. It's a shell similar to 'scapy' but this is the Perl version based on the Net::Frame modules.

    Find it here:

    Script: http://www.vinsworld.com/software/ppc.zip
    Perldoc: http://www.vinsworld.com/software/ppc.html

    You'll need to get Net::Pcap running if you don't already have it going. Once all prereq's are installed, it's as easy as:

    VinsWorldcom@C:\Users\VinsWorldcom\tmp\ppc> ppc -i "Wireless Network C +onnection" Welcome to Perl Packet Crafter (PPC) Copyright (C) Michael Vincent 2012 Wireless Network Connection ppc> sendp packet ETHER,IPv4(src=>'192.168.10.10',dst=>'192.168.10.20' +,protocol=>NF_IPv4_PROTOCOL_UDP),UDP(src=>6544,dst=>514,payload=>'tes +t123'); . Sent 1 packet ppc>

    And tcpdump verfies:

    VinsWorldcom@C:\Users\VinsWorldcom> tcpdump -i4 -nevvXX udp port 514 tcpdump: listening on \Device\NPF_{731EA781-5FB3-4C71-944A-D70C7EE18AA +7} 21:00:28.058467 c0:cb:38:08:46:76 > 58:6d:8f:78:ad:40, ethertype IPv4 +(0x0800), length 49: (tos 0x0, ttl 128, id 56403, offset 0, flags [none], proto: + UDP (17), length: 35) 192.168.10.10.6544 > 192.168.10.20.514: [udp sum ok] [|sy +slog] 0x0000: 586d 8f78 ad40 c0cb 3808 4676 0800 4500 Xm.x.@..8.Fv +..E. 0x0010: 0023 dc53 0000 8011 c907 c0a8 0a0a c0a8 .#.S........ +.... 0x0020: 0a14 1990 0202 000f 02c3 7465 7374 3132 ..........te +st12 0x0030: 33 3 1 packets captured 28 packets received by filter 0 packets dropped by kernel

    And note if you're actually trying to send Syslog, there is a Net::Frame::Layer::Syslog module for that.

      Cool. Thanks for the info, i'll look into those. Yeah, what im working on is forwarding/creating syslog messages for a project. I have working code in C and wanted to port it over to perl as well. I started looking at using perl Socket but was sidetracked to Net::RawIP when i read it calculated the checksums for ya. Thou, it's looking like that this is not the case?
      - Will

        If you're looking to send Syslog, you don't need to craft custom UDP packets. You can use IO::Socket to create TCP and UDP packets without worrying about checksum calculation - it's done for you by the OS IP/socket stack.

        For Syslog specifically, just use Net::Syslog. You don't even need to worry about sockets with that - it's done behind the scenes.

        If you need to listen to / receive Syslog messages, have a look at Net::Syslogd.

Re: Net::RawIP - invalid checksum ?
by taint (Chaplain) on Dec 06, 2013 at 20:10 UTC
    Greetings williambender

    I don't have tcpdump installed, so I don't know that I can check it. But would the following possibly work

    use Net::RawIP; my $packet = new Net::RawIP(); $packet->set({ ip => { saddr => "192.168.10.10", daddr => "192.168.10.20" }, udp => { check => 0, source => 6544, dest => 514, data => 'test123' } });

    HTH

    --Chris

    Hey. I'm not completely useless. I can be used as a bad example.
    

      Negitive. I now get.. (Defaults to TCP, src/dst ports are now 0)

      14:46:44.553547 IP (tos 0x0, ttl 60, id 35744, offset 0, flags [DF], p +roto TCP (6), length 40) 192.168.10.10.0 > 192.168.10.20.0: Flags [DF], cksum 0xcd50 (incor +rect -> 0xd550), seq 0, win 65535, length 0

      If i use your example and just change...

      my $packet = new Net::RawIP({udp => {check => 0}});

      Or even..

      my $packet = new Net::RawIP({udp => {}});

      I still get a bad checkdum...

      4:47:22.542872 IP (tos 0x0, ttl 60, id 35885, offset 0, flags [DF], pr +oto UDP (17), length 35) 192.168.10.10.6544 > 192.168.10.20.514: [bad udp cksum 0xb59d -> 0 +xbd9d!] [|syslog]

      -Will

        Well. Like I said, I couldn't test it. I was just trying to help with a possible alternative.

        I notice after reading both the docs, and source. There's precious little, regarding the check option.

        OTOH I notice
        Net::RawIP::opt
        and
        Net::RawIP::udphdr
        Perhaps experimenting with them, might yield some positive results?

        Just a thought. Not being able to test it myself. I'm afraid that's all I got.

        Best wishes

        --Chris

        Hey. I'm not completely useless. I can be used as a bad example.