1# $OpenBSD: Packet.pm,v 1.5 2021/12/12 21:16:53 bluhm Exp $ 2 3# Copyright (c) 2010-2017 Alexander Bluhm <bluhm@openbsd.org> 4# 5# Permission to use, copy, modify, and distribute this software for any 6# purpose with or without fee is hereby granted, provided that the above 7# copyright notice and this permission notice appear in all copies. 8# 9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 17use strict; 18use warnings; 19 20package Packet; 21use parent 'Proc'; 22use Carp; 23use Socket; 24use Socket6; 25use IO::Socket; 26use IO::Socket::IP -register; 27 28use constant IPPROTO_DIVERT => 258; 29 30sub new { 31 my $class = shift; 32 my %args = @_; 33 $args{ktracefile} ||= "packet.ktrace"; 34 $args{logfile} ||= "packet.log"; 35 $args{up} ||= "Bound"; 36 $args{down} ||= "Shutdown $class"; 37 my $self = Proc::new($class, %args); 38 $self->{domain} 39 or croak "$class domain not given"; 40 41 if ($self->{ktrace}) { 42 unlink $self->{ktracefile}; 43 my @cmd = ("ktrace", "-f", $self->{ktracefile}, "-p", $$); 44 do { local $> = 0; system(@cmd) } 45 and die ref($self), " system '@cmd' failed: $?"; 46 } 47 48 my $ds = do { local $> = 0; IO::Socket->new( 49 Type => Socket::SOCK_RAW, 50 Proto => IPPROTO_DIVERT, 51 Domain => $self->{domain}, 52 ) } or die ref($self), " socket failed: $!"; 53 my $sa; 54 $sa = pack_sockaddr_in($self->{bindport}, Socket::INADDR_ANY) 55 if $self->{af} eq "inet"; 56 $sa = pack_sockaddr_in6($self->{bindport}, Socket::IN6ADDR_ANY) 57 if $self->{af} eq "inet6"; 58 $ds->bind($sa) 59 or die ref($self), " bind failed: $!"; 60 my $log = $self->{log}; 61 print $log "divert sock: ",$ds->sockhost()," ",$ds->sockport(),"\n"; 62 $self->{divertaddr} = $ds->sockhost(); 63 $self->{divertport} = $ds->sockport(); 64 $self->{ds} = $ds; 65 66 if ($self->{ktrace}) { 67 my @cmd = ("ktrace", "-c", "-f", $self->{ktracefile}, "-p", $$); 68 do { local $> = 0; system(@cmd) } 69 and die ref($self), " system '@cmd' failed: $?"; 70 } 71 72 return $self; 73} 74 75sub child { 76 my $self = shift; 77 my $ds = $self->{ds}; 78 79 open(STDIN, '<&', $ds) 80 or die ref($self), " dup STDIN failed: $!"; 81 open(STDOUT, '>&', $ds) 82 or die ref($self), " dup STDOUT failed: $!"; 83} 84 851; 86