importos
importsys
importstruct
importselect
importtime
importtraceback
fromoslo.config importcfg
fromnova.openstack.common importlog as logging
fromeventlet.green importsocket
icmp_opts
=
[
cfg.StrOpt(
'timeout'
,
default
=
3
,
help
=
'Setting socket timeout'
),
cfg.StrOpt(
'count'
,
default
=
9
,
help
=
'Setting the IMCP PING'
),
]
CONF
=
cfg.CONF
CONF.register_opts(icmp_opts)
LOG
=
logging.getLogger(__name__)
ICMP_ECHO_REQUEST
=
8
defchecksum(source_string):
sum
=
0
countTo
=
(
len
(source_string)
/
2
)
*
2
count
=
0
whilecount<countTo:
thisVal
=
ord
(source_string[count
+
1
])
*
256
+
ord
(source_string[count])
sum
=
sum
+
thisVal
sum
=
sum
&
0xffffffff
count
=
count
+
2
ifcountTo<
len
(source_string):
sum
=
sum
+
ord
(source_string[
len
(source_string)
-
1
])
sum
=
sum
&
0xffffffff
sum
=
(
sum
>>
16
)
+
(
sum
&
0xffff
)
sum
=
sum
+
(
sum
>>
16
)
answer
=
~
sum
answer
=
answer &
0xffff
answer
=
answer >>
8
| (answer <<
8
&
0xff00
)
returnanswer
defreceive_one_ping(ping_socket,
ID
, timeout):
timeLeft
=
timeout
whileTrue:
startedSelect
=
time.clock()
whatReady
=
select.select([ping_socket], [], [], timeLeft)
howLongInSelect
=
(time.clock()
-
startedSelect)
ifwhatReady[
0
]
=
=
[]:
return
timeReceived
=
time.clock()
recPacket, addr
=
ping_socket.recvfrom(
1024
)
icmpHeader
=
recPacket[
20
:
28
]
type
, code, checksum, packetID, sequence
=
struct.unpack(
"bbHHh"
, icmpHeader
)
ifpacketID
=
=
ID
:
bytesInDouble
=
struct.calcsize(
"d"
)
timeSent
=
struct.unpack(
"d"
, recPacket[
28
:
28
+
bytesInDouble])[
0
]
returntimeReceived
-
timeSent
timeLeft
=
timeLeft
-
howLongInSelect
iftimeLeft <
=
0
:
return
defsend_one_ping(ping_socket, dest_addr,
ID
):
dest_addr
=
socket.gethostbyname(dest_addr)
my_checksum
=
0
header
=
struct.pack(
"bbHHh"
, ICMP_ECHO_REQUEST,
0
, my_checksum,
ID
,
1
)
bytesInDouble
=
struct.calcsize(
"d"
)
data
=
(
192
-
bytesInDouble)
*
"Q"
data
=
struct.pack(
"d"
, time.clock())
+
data
my_checksum
=
checksum(header
+
data)
header
=
struct.pack(
"bbHHh"
, ICMP_ECHO_REQUEST,
0
, socket.htons(my_checksum),
ID
,
1
)
packet
=
header
+
data
ping_socket.sendto(packet, (dest_addr,
1
))
defdo_one(dest_addr, timeout):
icmp
=
socket.getprotobyname(
"icmp"
)
try
:
ping_socket
=
socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
exceptsocket.error, (errno, msg):
iferrno
=
=
1
:
msg
=
msg
+
(
" - Note that ICMP messages can only be sent from processes"
" running as root."
)
LOG.error(socket.error(msg))
raise
my_ID
=
os.getpid() &
0xFFFF
send_one_ping(ping_socket, dest_addr, my_ID)
delay
=
receive_one_ping(ping_socket, my_ID, timeout)
ping_socket.close()
returndelay
deficmp_ping(dest_addr):
active
=
False
fori inxrange(CONF.count):
try
:
delay
=
do_one(dest_addr, CONF.timeout)
exceptsocket.gaierror, e:
active
=
False
break
ifdelay
=
=
None
:
active
=
False
else
:
active
=
True
return
active