Hullo..its me again..
i have been using Perl for 3 months now(still a novice, so please forgive me if my code looks bad)..and i'm trying to make a module..which is a Dhcpclient..(yes, there are modules in CPAN for a Dhcpclient, but for now i want to create my own module to broaden my knowledge).
Right now i am stuck and not quite sure if i am doing the right thing and before i proceed with this module i need to know if i am on the right track....
and i humbly ask for your guidance on this one so that i can achieve my goal(learning perl).
Here's my code:
package Dhcpclient;
use strict;
use warnings;
use Net::PcapUtils;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::UDP;
use Net::RawIP;
use Net::DHCP::Packet;
use Net::DHCP::Constants;
sub new {
my $class=shift;
my $self= {};
my %args = @_;
bless ($self,$class);
exists($args{Server}) ? $self->serverid($args{Server}) : $self->{S
+ERVER} = "0.0.0.0";
exists($args{Requestip}) ? $self->requestip($args{Requestip}) : $s
+elf->{REQIP} = "0.0.0.0";
exists($args{Releaseip}) ? $self->releaseip($args{Releaseip}) : $s
+elf->{RELIP} = "0.0.0.0";
exists($args{State}) ? $self->state($args{State}) : $self->{STATE}
+ = "INIT";
exists($args{Interface}) ? $self->interface($args{Interface}) : $s
+elf->{INTERFACE} = "eth0";
exists($args{Mac}) ? $self->genmac($args{Mac}) : $self->{MACADDRES
+S} = genmac();
return $self;
}
sub serverid
{
my $self = shift;
if (@_)
{ $self->{SERVER} = shift}
return $self->{SERVER};
}
sub requestip
{
my $self = shift;
if (@_)
{$self->{REQIP} = shift}
return $self->{REQIP};
}
sub releaseip
{
my $self = shift;
if (@_)
{$self->{RELIP} = shift}
return $self->{RELIP};
}
sub state
{
my $self = shift;
if (@_)
{$self->{STATE} = shift}
return $self->{STATE};
}
sub interface
{
my $self = shift;
if (@_)
{ $self->{INTERFACE} = shift}
return $self->{INTERFACE};
}
sub genmac
{
my $test_mac="004d";
my $a=0;
while($a++<4)
{
$test_mac.= sprintf("%x",int rand 16);
$test_mac.= sprintf("%x",int rand 16);
}
return $test_mac;
}
sub createpacket
{
my $self=shift;
my $state = $self->{STATE};
my $p;
my $data;
if ( $state eq 'Release')
{
$p= Net::DHCP::Packet->new(op => '1',
hlen=> '6',
htype=> '1',
hops => '0');
$p->chaddr($self->{MACADDRESS});
$p->xid(int(rand(0xFFFFFFFF)));
$p->isDhcp();
$p->ciaddr($self->{RELIP});
$p->addOptionValue(DHO_DHCP_MESSAGE_TYPE(), 7);
$p->addOptionValue(DHO_DHCP_SERVER_IDENTIFIER(), $self->{S
+ERVER});
$data=$p->serialize();
return $data;
}
elsif ( $state eq 'Request')
{
$p= Net::DHCP::Packet->new(op => '1',
hlen=> '6',
htype=> '1',
hops => '0');
$p->chaddr($self->{MACADDRESS});
$p->xid(int(rand(0xFFFFFFFF)));
$p->isDhcp();
$p->addOptionValue(DHO_DHCP_MESSAGE_TYPE(), 3)
+;
$p->addOptionValue(DHO_DHCP_SERVER_IDENTIFIER(
+), $self->{SERVER});
$p->addOptionValue(DHO_DHCP_REQUESTED_ADDRESS(
+), $self->{REQIP});
$data=$p->serialize();
return $data;
}
}
sub packetsend
{
my $self= shift;
my $data=$self->createpacket();
my $n =Net::RawIP->new({ ip=> {
saddr => '0.0.0.0',
daddr => '255.255.255.255',
},
udp => {
source => 68,
dest => 67,
data => $data
}
});
my $mac=$self->{MACADDRESS};
my @macar = split //, $mac;
my $i;
my $macjoin;
my $counter=0;
foreach $i (@macar)
{
$macjoin.=$i;
$counter++;
if($counter%2==0)
{
$macjoin.=":";
}
}
chop($macjoin);
$n->ethnew($self->{INTERFACE});
$n->ethset( source => $macjoin, dest => 'ff:ff:ff:ff:ff:ff');
$n->ethsend;
if ($self->{STATE} eq 'Request')
{
$self->getack();
}
}
sub printpacket
{
my $self=shift;
my $data=$self->createpacket();
my $p= Net::DHCP::Packet->new($data);
print $p->toString();
}
sub getack
{
my $self=shift;
my $packetcap1= Net::PcapUtils::open( FILTER =>'udp' , DEV => $sel
+f->{INTERFACE}, SNAPLEN => 400);
my ($packetcap, %hdr)=Net::PcapUtils::next($packetcap1);
my $ethpack=NetPacket::Ethernet->decode($packetcap);
my $ipack=NetPacket::IP->decode($ethpack->{data});
my $udpack=NetPacket::UDP->decode($ipack->{data});
my $capture=Net::DHCP::Packet->new($udpack->{data});
my $smac=sprintf ($ethpack->{src_mac});
my $dmac=sprintf ($ethpack->{dest_mac});
my $srcmac= sprintf("%s%s:%s%s:%s%s:%s%s:%s%s:%s%s", split//, $sma
+c);
my $destmac= sprintf("%s%s:%s%s:%s%s:%s%s:%s%s:%s%s", split//, $dm
+ac);
print ("====================BOOT REPLY========================\n")
+;
print "\n";
print $ipack->{src_ip} . "=====>" . $ipack->{dest_ip} . "(id : $ip
+ack->{id}, ttl: $ipack->{ttl})" . "\n";
print "UDP Source: $udpack->{src_port} ==> UDP Destination: $udpa
+ck->{dest_port} \n";
print "UDP Length: $udpack->{len}, UDP Data Length:", length($udpa
+ck->{data})," \n";
print "UDP Checksum: $udpack->{cksum} \n";
print "\n";
print "Source Mac address is : ".$srcmac."=====>";
print "Destination Mac address is: " . $destmac."\n";
my $ethtype=sprintf("%0.4x", $ethpack->{type});
print "Ethertype: ". $ethtype . "\n";
print "\n";
print ("====================UDP PACKET========================\n")
+;
print $capture->toString()."\n";
}
1;
i would really appreciate any advice,comments,suggestions or opinion on what i am doing. i know i still have a lot to learn...again i humbly seek your guidance..
Thanks in advance..