all the python scripts are for python2, and fedora31 requires to be specific
[vsys-scripts.git] / root-context / exec / promisc
1 #!/usr/bin/python2
2 # Vsys script to set a device in promisc mode
3 # The user needs to have the device allocated to him
4 # via the vsys_vnet tag. Set vsys_vnet to the IP address of
5 # the device. 
6 #
7 # From the slice:
8 # cat > /vsys/promisc.in
9 # vif312
10 # ^D
11
12 # To disable promisc mode:
13 #
14 # cat > /vsys/promisc.in
15 # vif312
16 # -
17 # ^D
18 #
19 # (Notice the - on a newline)
20
21
22 import sys
23 import pwd
24 import re
25 import socket
26 import struct
27 import os
28 import string
29 import fcntl
30
31 vsys_config_dir = "/etc/planetlab/vsys-attributes"
32
33 def get_ip_address(ifname):
34     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
35     return socket.inet_ntoa(fcntl.ioctl(
36         s.fileno(),
37         0x8915,  # SIOCGIFADDR
38         struct.pack('256s', ifname[:15])
39     )[20:24])
40
41 if len(sys.argv) != 2: sys.exit(1)
42
43 slicename=sys.argv[1]
44 netblock_config=os.path.join(vsys_config_dir,slicename,"vsys_vnet")
45
46 # Read netblock allocation file
47 base = None
48
49 for netblock in open(netblock_config,'r'):
50     base, mask = netblock.split('/')
51
52 if base is None:
53     print >>sys.stderr, "Could not find entry for slice %s in netblock config file %s" % (slicename, netblock_config)
54     sys.exit(1)
55
56 ### Read args from stdin
57 arglines = map(string.strip, sys.stdin.readlines())
58
59 if len(arglines)<1:
60     print >>sys.stderr, "Insufficient argument lines."
61     sys.exit(1)
62
63 vif = arglines[0] # interface name
64
65 if (len(arglines)==2 and arglines[1]=='-'):
66     neg = True
67 else:
68     neg = False
69
70 vip = get_ip_address(vif)
71
72
73 # Convert network base addr to int format by unpacking as 32bit net-ordered long (!L)
74 base_int = struct.unpack('!L',socket.inet_aton(base))[0]
75 mask = int(mask)
76
77 ### Validate args
78 # Validate interface name
79 if len(vif)>16:
80     print >>sys.stderr, "Interface name %s invalid"%(vif)
81     sys.exit(1)
82
83 try:
84     vip_int = struct.unpack('!L',socket.inet_aton(vip))[0]
85 except socket.error:
86     print >>sys.stderr, "Invalid IP: %s" % vip
87     sys.exit(1)
88
89 # Check IP is in netblock
90 if (vip_int>>(32-mask)) != (base_int>>(32-mask)):
91     print >>sys.stderr, "Requested IP %s not in netblock %s/%d" % (vip,base,mask)
92     sys.exit(1)
93
94 # OK. All checks passed. We can now act on the device.
95
96 if (not neg):
97     os.system('ifconfig %s promisc'%vif)
98 else:
99     os.system('ifconfig %s -promisc'%vif)