Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
snf-nfdhcpd
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
itminedu
snf-nfdhcpd
Commits
fd7ca450
Commit
fd7ca450
authored
Oct 04, 2012
by
Dimitris Aragiorgis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
One socket per client and few logging fixes
Signed-off-by:
Dimitris Aragiorgis
<
dimara@grnet.gr
>
parent
3f442273
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
76 additions
and
61 deletions
+76
-61
nfdhcpd
nfdhcpd
+76
-61
No files found.
nfdhcpd
View file @
fd7ca450
...
...
@@ -251,12 +251,47 @@ class Client(object):
self
.
gateway6
=
gateway6
self
.
net6
=
Subnet
(
net
=
subnet6
,
gw
=
gateway6
,
dev
=
tap
)
self
.
eui64
=
eui64
self
.
open_socket
()
def
is_valid
(
self
):
return
self
.
mac
is
not
None
and
self
.
ip
is
not
None
\
and
self
.
hostname
is
not
None
def
open_socket
(
self
):
logging
.
info
(
" - Opening L2 socket and binding to %s"
,
self
.
tap
)
try
:
s
=
socket
.
socket
(
socket
.
AF_PACKET
,
socket
.
SOCK_RAW
,
ETH_P_ALL
)
s
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_RCVBUF
,
0
)
s
.
bind
((
self
.
tap
,
ETH_P_ALL
))
self
.
socket
=
s
except
socket
.
error
,
e
:
logging
.
warning
(
" - Cannot open socket %s"
,
e
)
def
sendp
(
self
,
data
):
if
isinstance
(
data
,
BasePacket
):
data
=
str
(
data
)
logging
.
debug
(
" - Sending raw packet %r"
,
data
)
try
:
count
=
self
.
socket
.
send
(
data
,
socket
.
MSG_DONTWAIT
)
except
socket
.
error
,
e
:
logging
.
warn
(
" - Send with MSG_DONTWAIT failed: %s"
,
str
(
e
))
self
.
socket
.
close
()
self
.
open_socket
()
raise
e
ldata
=
len
(
data
)
logging
.
debug
(
" - Sent %d bytes on %s"
,
count
,
self
.
tap
)
if
count
!=
ldata
:
logging
.
warn
(
" - Truncated msg: %d/%d bytes sent"
,
count
,
ldata
)
class
Subnet
(
object
):
def
__init__
(
self
,
net
=
None
,
gw
=
None
,
dev
=
None
):
if
isinstance
(
net
,
str
):
...
...
@@ -364,7 +399,6 @@ class VMNetProxy(object): # pylint: disable=R0902
#self.ifaces = {}
#self.v6nets = {}
self
.
nfq
=
{}
self
.
l2socket
=
self
.
_socket
()
# Inotify setup
self
.
wm
=
pyinotify
.
WatchManager
()
...
...
@@ -376,7 +410,7 @@ class VMNetProxy(object): # pylint: disable=R0902
# NFQUEUE setup
if
dhcp_queue_num
is
not
None
:
self
.
_setup_nfqueue
(
dhcp_queue_num
,
AF_INET
,
self
.
dhcp_response
,
500
0
)
self
.
_setup_nfqueue
(
dhcp_queue_num
,
AF_INET
,
self
.
dhcp_response
,
0
)
if
rs_queue_num
is
not
None
:
self
.
_setup_nfqueue
(
rs_queue_num
,
AF_INET6
,
self
.
rs_response
,
10
)
...
...
@@ -386,14 +420,6 @@ class VMNetProxy(object): # pylint: disable=R0902
self
.
_setup_nfqueue
(
ns_queue_num
,
AF_INET6
,
self
.
ns_response
,
10
)
self
.
ipv6_enabled
=
True
def
_socket
(
self
):
logging
.
info
(
"Opening L2 socket"
)
try
:
s
=
socket
.
socket
(
socket
.
AF_PACKET
,
socket
.
SOCK_RAW
,
ETH_P_ALL
)
s
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_RCVBUF
,
0
)
except
socket
.
error
,
e
:
logging
.
warning
(
" - Cannot open socket %s"
,
e
)
return
s
def
_cleanup
(
self
):
""" Free all resources for a graceful exit
...
...
@@ -402,12 +428,9 @@ class VMNetProxy(object): # pylint: disable=R0902
logging
.
info
(
"Cleaning up"
)
logging
.
debug
(
" - Closing netfilter queues"
)
for
q
in
self
.
nfq
.
values
():
for
q
,
num
in
self
.
nfq
.
values
():
q
.
close
()
logging
.
debug
(
" - Closing socket"
)
self
.
l2socket
.
close
()
logging
.
debug
(
" - Stopping inotify watches"
)
self
.
notifier
.
stop
()
...
...
@@ -425,29 +448,14 @@ class VMNetProxy(object): # pylint: disable=R0902
self
.
nfq
[
q
.
get_fd
()]
=
(
q
,
pending
)
logging
.
debug
(
" - Successfully set up NFQUEUE %d"
,
queue_num
)
def
sendp
(
self
,
data
,
dev
):
def
sendp
(
self
,
data
,
binding
):
""" Send a raw packet using a layer-2 socket
"""
if
isinstance
(
data
,
BasePacket
):
data
=
str
(
data
)
logging
.
info
(
" - Sending raw packet on %s (%s)"
,
binding
.
tap
,
binding
.
hostname
)
binding
.
sendp
(
data
)
logging
.
debug
(
" - Sending raw packet %r"
,
data
)
self
.
l2socket
.
bind
((
dev
,
ETH_P_ALL
))
try
:
count
=
self
.
l2socket
.
send
(
data
,
socket
.
MSG_DONTWAIT
)
except
socket
.
error
,
e
:
logging
.
warn
(
" - Send with MSG_DONTWAIT failed: %s"
,
str
(
e
))
self
.
l2socket
.
close
()
self
.
l2socket
=
self
.
_socket
()
raise
e
ldata
=
len
(
data
)
logging
.
debug
(
" - Sent %d bytes to device %s"
,
count
,
dev
)
if
count
!=
ldata
:
logging
.
warn
(
" - Truncated send on %s (%d/%d bytes sent)"
,
dev
,
count
,
ldata
)
def
build_config
(
self
):
self
.
clients
.
clear
()
...
...
@@ -526,7 +534,7 @@ class VMNetProxy(object): # pylint: disable=R0902
"""
tap
=
os
.
path
.
basename
(
path
)
logging
.
debug
(
"Updating configuration for %s"
,
tap
)
logging
.
info
(
"Updating configuration for %s"
,
tap
)
b
=
parse_binding_file
(
path
)
if
b
is
None
:
return
...
...
@@ -551,18 +559,21 @@ class VMNetProxy(object): # pylint: disable=R0902
try
:
for
k
,
cl
in
self
.
clients
.
items
():
if
cl
.
tap
==
tap
:
logging
.
debug
(
"Removing client on interface %s"
,
tap
)
logging
.
debug
(
"%10s | %10s %20s %10s %20s"
,
logging
.
info
(
"Removing client %s and closing socket on %s"
,
cl
.
hostname
,
cl
.
tap
)
logging
.
debug
(
" - %10s | %10s %20s %10s %20s"
,
k
,
cl
.
hostname
,
cl
.
mac
,
cl
.
tap
,
cl
.
ip
)
cl
.
socket
.
close
()
del
self
.
clients
[
k
]
except
:
logging
.
debug
(
"Client on %s disappeared!!!"
,
tap
)
def
dhcp_response
(
self
,
dummy
,
payload
):
# pylint: disable=W0613,R0914
""" Generate a reply to bnetfilter-queue-deva BOOTP/DHCP request
"""
logging
.
debug
(
" * Processing pending DHCP request"
)
logging
.
info
(
" * Processing pending DHCP request"
)
# Decode the response - NFQUEUE relays IP packets
pkt
=
IP
(
payload
.
get_data
())
#logging.debug(pkt.show())
...
...
@@ -596,7 +607,7 @@ class VMNetProxy(object): # pylint: disable=R0902
logging
.
warn
(
" - Recieved spoofed DHCP request for mac %s from tap %s"
,
mac
,
indev
)
return
logging
.
debug
(
" - Generating DHCP response for host %s (mac %s) on tap %s"
,
logging
.
info
(
" - Generating DHCP response for host %s (mac %s) on tap %s"
,
binding
.
hostname
,
mac
,
binding
.
tap
)
...
...
@@ -671,18 +682,19 @@ class VMNetProxy(object): # pylint: disable=R0902
logging
.
info
(
" - %s to %s (%s) on %s"
,
DHCP_TYPES
[
resp_type
],
mac
,
binding
.
ip
,
binding
.
tap
)
try
:
self
.
sendp
(
resp
,
binding
.
indev
)
self
.
sendp
(
resp
,
binding
)
except
socket
.
error
,
e
:
logging
.
warn
(
" - DHCP response on %s failed: %s"
,
binding
.
indev
,
str
(
e
))
logging
.
warn
(
" - DHCP response on %s (%s) failed: %s"
,
binding
.
tap
,
binding
.
hostname
,
str
(
e
))
except
Exception
,
e
:
logging
.
warn
(
" - Unkown error during DHCP response on %s: %s"
,
binding
.
indev
,
str
(
e
))
logging
.
warn
(
" - Unkown error during DHCP response on %s
(%s)
: %s"
,
binding
.
tap
,
binding
.
hostname
,
str
(
e
))
def
rs_response
(
self
,
dummy
,
payload
):
# pylint: disable=W0613
""" Generate a reply to a BOOTP/DHCP request
"""
logging
.
debug
(
" * Processing pending RS request"
)
logging
.
info
(
" * Processing pending RS request"
)
pkt
=
IPv6
(
payload
.
get_data
())
#logging.debug(pkt.show())
try
:
...
...
@@ -722,7 +734,7 @@ class VMNetProxy(object): # pylint: disable=R0902
if
ifll
is
None
:
return
logging
.
debug
(
" - Generating RA for host %s (mac %s) on tap %s"
,
logging
.
info
(
" - Generating RA for host %s (mac %s) on tap %s"
,
binding
.
hostname
,
mac
,
binding
.
tap
)
resp
=
Ether
(
src
=
indevmac
)
/
\
...
...
@@ -735,19 +747,20 @@ class VMNetProxy(object): # pylint: disable=R0902
lifetime
=
self
.
ra_period
*
3
)
try
:
self
.
sendp
(
resp
,
binding
.
indev
)
self
.
sendp
(
resp
,
binding
)
except
socket
.
error
,
e
:
logging
.
warn
(
" - RA on %s failed: %s"
,
binding
.
indev
,
str
(
e
))
logging
.
warn
(
" - RA on %s (%s) failed: %s"
,
binding
.
tap
,
binding
.
hostname
,
str
(
e
))
except
Exception
,
e
:
logging
.
warn
(
" - Unkown error during RA on %s: %s"
,
binding
.
indev
,
str
(
e
))
logging
.
warn
(
" - Unkown error during RA on %s
(%s)
: %s"
,
binding
.
tap
,
binding
.
hostname
,
str
(
e
))
def
ns_response
(
self
,
dummy
,
payload
):
# pylint: disable=W0613
""" Generate a reply to an ICMPv6 neighbor solicitation
"""
logging
.
debug
(
" * Processing pending NS request"
)
logging
.
info
(
" * Processing pending NS request"
)
ns
=
IPv6
(
payload
.
get_data
())
#logging.debug(ns.show())
...
...
@@ -793,8 +806,8 @@ class VMNetProxy(object): # pylint: disable=R0902
logging
.
debug
(
" - Received NS for a non-routable IP (%s)"
,
ns
.
tgt
)
return
1
logging
.
debug
(
" - Generating NA for host %s (mac %s) on tap %s"
,
binding
.
hostname
,
mac
,
binding
.
tap
)
logging
.
info
(
" - Generating NA for host %s (mac %s) on tap %s"
,
binding
.
hostname
,
mac
,
binding
.
tap
)
resp
=
Ether
(
src
=
indevmac
,
dst
=
binding
.
mac
)
/
\
IPv6
(
src
=
str
(
ifll
),
dst
=
ns
.
src
)
/
\
...
...
@@ -802,12 +815,13 @@ class VMNetProxy(object): # pylint: disable=R0902
ICMPv6NDOptDstLLAddr
(
lladdr
=
indevmac
)
try
:
self
.
sendp
(
resp
,
binding
.
indev
)
self
.
sendp
(
resp
,
binding
)
except
socket
.
error
,
e
:
logging
.
warn
(
" - NA on %s failed: %s"
,
binding
.
indev
,
str
(
e
))
logging
.
warn
(
" - NA on %s (%s) failed: %s"
,
bindig
.
tap
,
binding
.
hostname
,
str
(
e
))
except
Exception
,
e
:
logging
.
warn
(
" - Unkown error during periodic NA
on %s
: %s"
,
binding
.
indev
,
str
(
e
))
logging
.
warn
(
" - Unkown error during periodic NA
to %s (%s)
: %s"
,
binding
.
tap
,
binding
.
hostname
,
str
(
e
))
def
send_periodic_ra
(
self
):
# Use a separate thread as this may take a _long_ time with
...
...
@@ -815,7 +829,7 @@ class VMNetProxy(object): # pylint: disable=R0902
threading
.
Thread
(
target
=
self
.
_send_periodic_ra
).
start
()
def
_send_periodic_ra
(
self
):
logging
.
debug
(
"Sending out periodic RAs"
)
logging
.
info
(
"Sending out periodic RAs"
)
start
=
time
.
time
()
i
=
0
for
binding
in
self
.
clients
.
values
():
...
...
@@ -839,14 +853,15 @@ class VMNetProxy(object): # pylint: disable=R0902
resp
/=
ICMPv6NDOptRDNSS
(
dns
=
self
.
ipv6_nameservers
,
lifetime
=
self
.
ra_period
*
3
)
try
:
self
.
sendp
(
resp
,
indev
)
self
.
sendp
(
resp
,
binding
)
except
socket
.
error
,
e
:
logging
.
warn
(
" - Periodic RA on %s failed: %s"
,
tap
,
str
(
e
))
logging
.
warn
(
" - Periodic RA on %s (%s) failed: %s"
,
tap
,
binding
.
hostname
,
str
(
e
))
except
Exception
,
e
:
logging
.
warn
(
" - Unkown error during periodic RA on %s
: %s"
,
tap
,
str
(
e
))
logging
.
warn
(
" - Unkown error during periodic RA on %s
(%s):"
" %s"
,
tap
,
binding
.
hostname
,
str
(
e
))
i
+=
1
logging
.
debug
(
" - Sent %d RAs in %.2f seconds"
,
i
,
time
.
time
()
-
start
)
logging
.
info
(
" - Sent %d RAs in %.2f seconds"
,
i
,
time
.
time
()
-
start
)
def
serve
(
self
):
""" Safely perform the main loop, freeing all resources upon exit
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment