Search code examples
perlpcap

How do I modify the destination MAC address in a packet?


I've a question related to a very basic thing in Perl, but I'm unable to find an efficient solution.

Here's a bit of context first. I use Net::Pcap etc and when I'm in my function which processes packets (used by pcap_loop) I get a $packet scalar which contains my whole packet (ethernet header + ip header + tcp/udp header + payload).

What I want to do is to change the first 6 bytes of this $packet (the ethernet destination) in order to get a $packet that I can send using pcap_sendpacket, using a user defined destination mac address (for example passed as a command line argument or so), such as 00:11:22:33:44:55. So I can split the user defined address (using split for example) to get every 6 parts of the destination mac address, and convert it to hex using the hex function, but now I want to modify the first bytes of my packet to replace them with these hexed bytes. How should I proceed ?

I thought using some concatenation (.) but I think that this solution is dirty.

Thinking in C (because I did it in C some time ago, but I want this to be done in Perl), Once I got my "u_char packet[]", I just had to do a memcpy of my user-supplied ethernet address to the 6 first bytes of my packet[] and it worked.


Solution

  • The vec function is used to work with a scalar value as a bit vector.

    use strict;
    use warnings;
    
    my $packet;
    # set packet to something...
    
    my $address = '00:11:22:33:44:55';
    my @bytes   = map { hex } split(/:/, $address);
    for my $i (0 .. $#bytes) {
        vec($packet, $i, 8) = $bytes[$i];
    }