#
# Helper functions
# This will be part of the hping standard library (possibly modified)
#
################################################################################
# Functions related to network interface managment
################################################################################
# Return the name of the output interface for address addr
proc outifname addr {
set ifa [hping outifa $addr]
set interfaces [hping iflist]
foreach i $interfaces {
foreach ia [lindex $i 2] {
if {$ifa == $ia} {
return [lindex $i 0]
}
}
}
error "Unable to find the output interface name for $addr"
}
################################################################################
# Functions related to packets description
################################################################################
interp alias {} GetApdField {} hping getfield
proc SetApdField {protocol field value pvar} {
upvar $pvar p
set p [hping setfield $protocol $field $value $p]
}
proc DelApdField {protocol field pvar} {
upvar $pvar p
set p [hping delfield $protocol $field $p]
}
interp alias {} GetIpSaddr {} hping getfield ip saddr
interp alias {} GetIpDaddr {} hping getfield ip daddr
interp alias {} GetIpTtl {} hping getfield ip ttl
interp alias {} GetIpProto {} hping getfield ip proto
interp alias {} GetTcpSport {} hping getfield tcp sport
interp alias {} GetTcpDport {} hping getfield tcp dport
interp alias {} GetTcpSeq {} hping getfield tcp seq
interp alias {} GetTcpAck {} hping getfield tcp ack
interp alias {} GetTcpTimestampVal {} hping getfield tcp.timestamp val
interp alias {} GetTcpTimestampEcr {} hping getfield tcp.timestamp ecr
interp alias {} GetIcmpType {} hping getfield icmp type
interp alias {} GetIcmpCode {} hping getfield icmp code
interp alias {} GetIcmpId {} hping getfield icmp id
interp alias {} GetIcmpSeq {} hping getfield icmp seq
interp alias {} GetDataHex {} hping getfield data hex
# From APD to Tcl list
proc apd2list apd {
set list {}
foreach layer [split $apd +] {
set t [split $layer ()]
set name [lindex $t 0]
set fields [lindex $t 1]
set l [list $name]
foreach fieldvalue [split $fields ,] {
foreach {field value} [split $fieldvalue =] break
lappend l [list $field $value]
}
lappend list $l
}
return $list
}
# From Tcl list to APD
proc list2apd list {
if {![llength $list]} return
foreach layer $list {
append apd [lindex $layer 0] (
set layer [lrange $layer 1 end]
foreach fieldvalue $layer {
append apd [lindex $fieldvalue 0] = [lindex $fieldvalue 1] ,
}
if {[llength $layer] != 0} {
set apd [string range $apd 0 end-1]
}
append apd )+
}
set apd [string range $apd 0 end-1]
return $apd
}
################################################################################
# High-level networking functions
################################################################################
# Return non-zero if the host addr seems awake.
# This is done sending a TCP ACK packet and an ICMP echo request
# and searching for at least a reply.
proc isawake addr {
set addr [hping resolve $addr]
set ifname [outifname $addr]
set ifaddr [hping outifa $addr]
hping recv eth0 0
set ip "ip(saddr=$ifaddr,daddr=$addr,ttl=64)"
append ack $ip "+tcp(sport=11005,dport=11111,flags=a)"
append icmp $ip "+icmp(type=8,code=8,id=11111)"
hping send $ack
hping send $icmp
for {set i 0} {$i < 10} {incr i} {
set packets [hping recv $ifname 100 0]
foreach p $packets {
if {([GetIpSaddr $p] == $addr) && (([GetIcmpId $p] == 11111) || ([GetTcpSport $p] == 11111))} {
return 1;
}
}
}
return 0;
}
# Todo, check the OS's version and to what needed.
proc DropOutgoingResets {} {
exec "iptables -A OUTPUT -p tcp -j DROP --tcp-flags RST RST"
}
################################################################################
# Non hping specific Tcl functions that seems to help
################################################################################
proc isempty l {
expr {[llength $l] == 0}
}
proc haskey {arrayname key} {
expr {[llength [uplevel "array names $arrayname -exact $key"]] != 0}
}
#
# End of the hping standard library
#
################################################################################
# vim: filetype=tcl