Skip to content

Commit 149c6ea

Browse files
committed
Fallback to busybox if udhcpc is not installed, and warn if /etc/udhcpc/default.script is missing (which it probably is)
1 parent 66ff173 commit 149c6ea

File tree

4 files changed

+66
-6
lines changed

4 files changed

+66
-6
lines changed

README-template.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ to `~/.bash_completion`.
7373
| `/usr/bin/pkill` | `procps` |
7474
| `/usr/sbin/openvpn` | `openvpn` |
7575
| `/usr/bin/wg` | `https://www.wireguard.com/install/` |
76-
| Python package `yaml` | `python-yaml` / PyPI `pyyaml` |
76+
| Python package `yaml` | `python3-yaml` / PyPI `pyyaml` |
7777

7878
It is also a good idea to uninstall resolvconf, as it overwrites the DNS settings.
7979

@@ -91,6 +91,14 @@ common:
9191
udhcpc-config: /etc/udhcpc/default.script
9292
```
9393

94+
### Bootstrapping
95+
96+
`net` will run even without `udhcpc` or `python3-yaml`, with limited
97+
functionality. In the former case information acquired via DHCP may not be
98+
reflected on the system, and in the latter the configuration file will not be
99+
used. However it may be enough to get online in order to fulfill the
100+
dependencies (tested on Debian 11).
101+
94102
## Contributors
95103

96104
If you want to contribute, feel free to make a pull request on [Github](https://github.com/Pwnies/net), please read [CONTRIBUTING](CONTRIBUTING) and [the license](UNLICENSE) first.

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ to `~/.bash_completion`.
217217
| `/usr/bin/pkill` | `procps` |
218218
| `/usr/sbin/openvpn` | `openvpn` |
219219
| `/usr/bin/wg` | `https://www.wireguard.com/install/` |
220-
| Python package `yaml` | `python-yaml` / PyPI `pyyaml` |
220+
| Python package `yaml` | `python3-yaml` / PyPI `pyyaml` |
221221

222222
It is also a good idea to uninstall resolvconf, as it overwrites the DNS settings.
223223

@@ -235,6 +235,14 @@ common:
235235
udhcpc-config: /etc/udhcpc/default.script
236236
```
237237

238+
### Bootstrapping
239+
240+
`net` will run even without `udhcpc` or `python3-yaml`, with limited
241+
functionality. In the former case information acquired via DHCP may not be
242+
reflected on the system, and in the latter the configuration file will not be
243+
used. However it may be enough to get online in order to fulfill the
244+
dependencies (tested on Debian 11).
245+
238246
## Contributors
239247

240248
If you want to contribute, feel free to make a pull request on [Github](https://github.com/Pwnies/net), please read [CONTRIBUTING](CONTRIBUTING) and [the license](UNLICENSE) first.

genREADME.py

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def expand(src, dst):
2424
stdin=open('/dev/null'),
2525
stdout=subprocess.PIPE,
2626
stderr=subprocess.STDOUT,
27+
text=True,
2728
)
2829
fd = p.stdout
2930
elif cmd == 'include':

net

+47-4
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,31 @@ def rm(*paths):
261261
except OSError:
262262
pass
263263

264+
# Ref: https://github.com/Gallopsled/pwntools/blob/dev/pwnlib/util/misc.py
265+
def which(name, all=False, path=None):
266+
isroot = os.getuid() == 0
267+
out = set()
268+
try:
269+
path = path or os.environ['PATH']
270+
except KeyError:
271+
log.exception('Environment variable $PATH is not set')
272+
for p in path.split(os.pathsep):
273+
p = os.path.join(p, name)
274+
if os.access(p, os.X_OK):
275+
st = os.stat(p)
276+
if not stat.S_ISREG(st.st_mode):
277+
continue
278+
# work around this issue: https://bugs.python.org/issue9311
279+
if isroot and not \
280+
st.st_mode & (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH):
281+
continue
282+
if all:
283+
out.add(p)
284+
else:
285+
return p
286+
if all:
287+
return out
288+
264289
def expand(path):
265290
if path.startswith('~/'):
266291
user = os.environ.get('SUDO_USER', '')
@@ -744,18 +769,35 @@ def do_scan(open_flag=None):
744769
for addr, quality in zip(addrs, qualities):
745770
print(' - %s %d dBm' % (addr, quality))
746771

747-
def start_dhcp_cmd(iface, hostname = None, udhcpc_config = None):
748-
cmd = 'udhcpc -R -i %s' % iface
772+
# If `udhcpc` is not instailled on the sytem we call it through `busybox`
773+
# instead. However, this probably means that the `udhcpc` default script is not
774+
# installed either. We warn about that in `start_dhcp_cmd` below.
775+
def udhcpc():
776+
return 'udhcpc' if which('udhcpc') else 'busybox udhcpc'
777+
778+
def start_dhcp_cmd(iface, hostname = None, udhcpc_config = None, warn_no_config = True):
779+
cmd = udhcpc() + ' -R -i %s' % iface
749780
if hostname:
750781
if hostname == 'system':
751782
hostname = run('hostname') or hostname
752783
cmd += ' -F %s' % hostname
753784
if udhcpc_config:
754785
cmd += ' -s %s' % udhcpc_config
786+
elif not os.path.isfile('/etc/udhcpc/default.script') and warn_no_config:
787+
print('!! No `udhcpc` configuration given and ' \
788+
'/etc/udhcpc/default.script does not exist')
789+
print('!! Acquired information will not be set')
790+
print('')
791+
print('Set IP and default gateway manually:')
792+
print('$ ip a add 192.168.0.99/24 dev <iface>')
793+
print('$ ip r add default via 192.168.0.1 dev <iface>')
794+
print('')
795+
print('Tip: See the used interface and acquired address by running ' \
796+
'with --verbose.')
755797
return cmd
756798

757799
def stop_dhcp_cmd(iface):
758-
pattern = start_dhcp_cmd(iface)
800+
pattern = start_dhcp_cmd(iface, warn_no_config = False)
759801
return 'pkill -f "^%s"' % pattern
760802

761803
def stop_dhcp(iface):
@@ -766,7 +808,8 @@ def renew_dhcp_cmd():
766808
# We only call this function in `do_dns', and this function is not aware of
767809
# which interface we are talking about. So: We renew them all and accept the
768810
# race condition.
769-
return 'pkill -SIGUSR1 udhcpc'
811+
pattern = udhcpc()
812+
return 'pkill -SIGUSR1 "^%s' % pattern
770813

771814
def renew_dhcp():
772815
run(renew_dhcp_cmd())

0 commit comments

Comments
 (0)