1################################################################################
2#
3# Helper functions
4# This will be part of the hping standard library (possibly modified)
5#
6
7################################################################################
8# Functions related to network interface managment
9################################################################################
10
11# Return the name of the output interface for address addr
12proc outifname addr {
13	set ifa [hping outifa $addr]
14	set interfaces [hping iflist]
15	foreach i $interfaces {
16		foreach ia [lindex $i 2] {
17			if {$ifa == $ia} {
18				return [lindex $i 0]
19			}
20		}
21	}
22	error "Unable to find the output interface name for $addr"
23}
24
25################################################################################
26# Functions related to packets description
27################################################################################
28
29interp alias {} GetApdField {} hping getfield
30
31proc SetApdField {protocol field value pvar} {
32        upvar $pvar p
33	set p [hping setfield $protocol $field $value $p]
34}
35
36proc DelApdField {protocol field pvar} {
37        upvar $pvar p
38	set p [hping delfield $protocol $field $p]
39}
40
41interp alias {} GetIpSaddr {} hping getfield ip saddr
42interp alias {} GetIpDaddr {} hping getfield ip daddr
43interp alias {} GetIpTtl {} hping getfield ip ttl
44interp alias {} GetIpProto {} hping getfield ip proto
45interp alias {} GetTcpSport {} hping getfield tcp sport
46interp alias {} GetTcpDport {} hping getfield tcp dport
47interp alias {} GetTcpSeq {} hping getfield tcp seq
48interp alias {} GetTcpAck {} hping getfield tcp ack
49interp alias {} GetTcpTimestampVal {} hping getfield tcp.timestamp val
50interp alias {} GetTcpTimestampEcr {} hping getfield tcp.timestamp ecr
51interp alias {} GetIcmpType {} hping getfield icmp type
52interp alias {} GetIcmpCode {} hping getfield icmp code
53interp alias {} GetIcmpId {} hping getfield icmp id
54interp alias {} GetIcmpSeq {} hping getfield icmp seq
55interp alias {} GetDataHex {} hping getfield data hex
56
57# From APD to Tcl list
58proc apd2list apd {
59    set list {}
60    foreach layer [split $apd +] {
61	set t [split $layer ()]
62	set name [lindex $t 0]
63	set fields [lindex $t 1]
64	set l [list $name]
65	foreach fieldvalue [split $fields ,] {
66	    foreach {field value} [split $fieldvalue =] break
67	    lappend l [list $field $value]
68	}
69	lappend list $l
70    }
71    return $list
72}
73
74# From Tcl list to APD
75proc list2apd list {
76    if {![llength $list]} return
77    foreach layer $list {
78	append apd [lindex $layer 0] (
79	set layer [lrange $layer 1 end]
80	foreach fieldvalue $layer {
81	    append apd [lindex $fieldvalue 0] = [lindex $fieldvalue 1] ,
82	}
83	if {[llength $layer] != 0} {
84	    set apd [string range $apd 0 end-1]
85	}
86	append apd )+
87    }
88    set apd [string range $apd 0 end-1]
89    return $apd
90}
91
92################################################################################
93# High-level networking functions
94################################################################################
95
96# Return non-zero if the host addr seems awake.
97# This is done sending a TCP ACK packet and an ICMP echo request
98# and searching for at least a reply.
99proc isawake addr {
100	set addr [hping resolve $addr]
101	set ifname [outifname $addr]
102	set ifaddr [hping outifa $addr]
103
104	hping recv eth0 0
105
106	set ip "ip(saddr=$ifaddr,daddr=$addr,ttl=64)"
107	append ack $ip "+tcp(sport=11005,dport=11111,flags=a)"
108	append icmp $ip "+icmp(type=8,code=8,id=11111)"
109
110	hping send $ack
111	hping send $icmp
112
113	for {set i 0} {$i < 10} {incr i} {
114		set packets [hping recv $ifname 100 0]
115		foreach p $packets {
116			if {([GetIpSaddr $p] == $addr) && (([GetIcmpId $p] == 11111) || ([GetTcpSport $p] == 11111))} {
117			     	return 1;
118			     }
119		}
120	}
121	return 0;
122}
123
124# Todo, check the OS's version and to what needed.
125proc DropOutgoingResets {} {
126	exec "iptables -A OUTPUT -p tcp -j DROP --tcp-flags RST RST"
127}
128
129################################################################################
130# Non hping specific Tcl functions that seems to help
131################################################################################
132
133proc isempty l {
134    expr {[llength $l] == 0}
135}
136
137proc haskey {arrayname key} {
138    expr {[llength [uplevel "array names $arrayname -exact $key"]] != 0}
139}
140
141#
142# End of the hping standard library
143#
144################################################################################
145
146# vim: filetype=tcl
147