Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Building a UDP Ethernet header

by TorNZZ (Novice)
on Sep 17, 2017 at 22:10 UTC ( [id://1199571]=perlquestion: print w/replies, xml ) Need Help??

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

I find this code and it sends UDP packet and all information in is ok, But in Ethernet header layer i find that the source mac-address is like: fe:ff:ff:ff:ff:ff So i ask how can i control the source mac address? How can i make sub-function to return the ethernet layer and i control of it like other layers?

#!/usr/bin/perl ###################################################################### +#### # Author: Lucas Thoresen + # # Attribution: cleen -> http://www.perlmonks.org/index.pl?node_id=1757 +6 # # Date: December 8, 2012 + # # Purpose: To demonstrate Perl UDP packet generation. + # # Hopefully someone will find this useful. :] + # ###################################################################### +#### use strict; use warnings; use Socket; # Source and destination IP/Hostname my $ip_src = (gethostbyname($ARGV[0]))[4]; my $ip_dst = (gethostbyname($ARGV[1]))[4]; # Check to see if all parameters are present if (!defined $ip_src or !defined $ip_dst) { exit "Usage: $0 <source ip> <destination ip>\n"; } # Setup the socket to be used 255 is IPPROTO_RAW) socket(RAW, AF_INET, SOCK_RAW, 255) or die $!; setsockopt(RAW, 0, 1, 1); main(); # Main program sub main { my $packet; # Add the layer 3 and 4 headers $packet = ip_header(); $packet .= udp_header(); # Add in a data section $packet .= payload(); # Fire! send_packet($packet); } # Builds an IP header (Layer 3) sub ip_header { my $ip_ver = 4; # IP Version 4 + (4 bits) my $ip_header_len = 5; # IP Header Length + (4 bits) my $ip_tos = 0; # Differentiated Servic +es (8 bits) my $ip_total_len = $ip_header_len + 20; # IP Header Length + Da +ta (16 bits) my $ip_frag_id = 0; # Identification Field + (16 bits) my $ip_frag_flag = '000'; # IP Frag Flags (R DF M +F) (3 bits) my $ip_frag_offset = '0000000000000'; # IP Fragment Offset + (13 bits) my $ip_ttl = 255; # IP TTL + (8 bits) my $ip_proto = 17; # IP Protocol + (8 bits) my $ip_checksum = 0; # IP Checksum + (16 bits) my $ip_header = pack( 'H2 H2 n n B16 h2 c n a4 a4', $ip_ver . $ip_header_len, $ip_tos, $ip_total_len, $ip_frag_id, $ip_frag_flag . $ip_frag_offset, $ip_ttl, $ip_proto, $ip_checksum, $ip_src, $ip_dst ); return $ip_header; } # Builds a UDP header (Layer 4) sub udp_header { my $udp_src_port = 60; # UDP Sort Port + (16 bits) my $udp_dst_port = 60; # UDP Dest Port + (16 btis) my $udp_len = 8 + length(payload()); # UDP Length + (16 bits) my $udp_checksum = 0; # UDP Checksum + (16 bits) my $udp_header = pack( 'n n n n', $udp_src_port, $udp_dst_port, $udp_len, $udp_checksum ); return $udp_header; } # Builds a data section sub payload { my $data = 'abcdefghijklmnopqrstuvwxyz hi'; # Pack the data in dynamically my $payload = pack( 'a' . length($data), $data ); return $payload; } # Send the packet sub send_packet { # @_ doesn't work, you need to use $_[0] as the param to the send +sub! send(RAW, $_[0], 0, pack('Sna4x8', AF_INET, 60, $ip_dst)); }

Replies are listed 'Best First'.
Re: Building a UDP Ethernet header
by VinsWorldcom (Prior) on Sep 18, 2017 at 10:31 UTC

    What is the purpose here? You can easily send UDP packets in Perl without having to craft them from raw sockets. If you have an actual use case for crafting UDP (or any packets for that matter), see Net::Frame suite. Otherwise, something like UDP Listener / Server should do the trick.

Re: Building a UDP Ethernet header
by Discipulus (Canon) on Sep 18, 2017 at 10:34 UTC
    Hello TorNZZ and welcome to the monastery and to the wonderful world of Perl

    Disclaimer: my network-fu is very limited (read: google).

    It seems to me that the MAC fe:ff:ff:ff:ff:ff must be something special, like a dummy MAC assigned to (virtual) interfaces. It is the last address of such used for Ipv4 Address Holder according to iana - ethernet numbers. It must be the broadcast address (see here)

    If i understand it correctly the MAC part, in the ethernet frame, is modified at each net device the UDP packet traverse. The MAC is normally added by the driver at the source(?).

    Anyway you might be interested in Re: transmit udp packets by VinsWorldcom that for sure has more experience than me. The post suggests Net::Pcap and Net::Filter Net::Frame as base resource.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      @VinsWorldcom, I found this: http://search.cpan.org/~gomor/Net-Frame-1.00/lib/Net/Frame/ETH.pm Can i add this to my code and then now i can change the source MAC? Can you write me example that suit my code?

      @Discipulus, So this Mac-Address is generated by my PC? (It's already Virtual Machine). My point is to add another layer to the code i have so i can control src mac address. Fix your Net::Filter link not works. And i need something that can be fitted to code i have.

      Thanks guys you are very helpful.

        You can't just add Net::Frame::Layer::ETH to your code. You need to properly install Net::Frame suite with 'cpan' client or other means (e.g., perl Makefile.PL; make; make install). You'll probably also need Net::Frame::Simple and Net::Pcap if you intend to send packets.

        Again, I go back to: "What are you trying to do?" There are much easier ways to send / receive UDP packets with Perl without crafting them from scratch. The only reasons *I* can think of for crafting raw packets is:

        • local network testing - which requires a very deep knowledge of protocols
        • something "nefarious"

        UPDATE: Reading your Stack Overflow post, your local and remote IP addresses are not in the same network, nevermind subnet. Sending crafted packets across the Internet reeks of malicious intent. Please explain what you're trying to do or I can't in good conscience offer more advice.

Re: Building a UDP Ethernet header
by thanos1983 (Parson) on Sep 18, 2017 at 08:50 UTC

    Hello TorNZZ,

    Welcome to the Monastery. If I have understand your question correctly I think that you are looking for something like that Net::MAC::Vendor.

    Update: I just came across with your duplicated question on relevant site Building a UDP Ethernet header. It would be good to let us know in such cases so people do not work on your answer twice.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

      @thanos1983, There no one helps me right so i try asking here, That's why i ask i'll delete the question on stackoverflow.

        It's better to interlink the questions rather than deleting one of them. It reduces the work of people answering them, but also broadens the numbers of people who might benefit from the answers.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Thanks for reply, So where i should put this in my code so packets mac-address i send change to what i set?

Re: Building a UDP Ethernet header
by danver (Initiate) on Nov 11, 2019 at 12:53 UTC
    I like it. I will come back

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1199571]
Approved by beech
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-04-19 12:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found