captiveportal_fakedns 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Net::DNS::Nameserver;
  5. use IO::Socket::INET;
  6. # This idea was stolen from Net::Address::IP::Local::connected_to()
  7. sub get_local_ip_address {
  8. my $socket = IO::Socket::INET->new(
  9. Proto => 'udp',
  10. PeerAddr => '198.41.0.4', # a.root-servers.net
  11. PeerPort => '53', # DNS
  12. );
  13. # A side-effect of making a socket connection is that our IP address
  14. # is available from the 'sockhost' method
  15. my $local_ip_address = $socket->sockhost;
  16. return $local_ip_address;
  17. }
  18. my $ip4_addr = get_local_ip_address();
  19. sub reply_handler {
  20. my ($qname, $qclass, $qtype, $peerhost,$query,$conn) = @_;
  21. my ($rcode, @ans, @auth, @add);
  22. if($qtype eq "A") {
  23. my ($ttl, $rdata) = (1, $ip4_addr);
  24. my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
  25. push @ans, $rr;
  26. $rcode = "NOERROR";
  27. } else {
  28. $rcode = "NXDOMAIN";
  29. }
  30. return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
  31. }
  32. my $ns = new Net::DNS::Nameserver(
  33. LocalPort => 4253,
  34. LocalAddr => '0.0.0.0',
  35. ReplyHandler => \&reply_handler,
  36. Verbose => 0
  37. ) || die "Couldn't create fake nameserver object.\n";
  38. $ns->main_loop;
  39. exit 0;