Last active
May 7, 2023 00:46
-
-
Save gnull/8728d7498bb6f61aa5bfa85d14de9152 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh -efux | |
# This file works only with IPv4. The variables in capitals are the parameters | |
# you can adjust to your needs | |
# The name of the modem network interface as shown in `ip a` | |
INTERFACE=wwp0s20f0u3i12 | |
# The access point address. This is the same value as the one you typically | |
# have in the internet settings of your mobile phone. | |
# | |
# Some common values are | |
# Altel KZ: internet, internet.altel.kz | |
# internet.tele2.kz | |
# internet.beeline.kz | |
# APN=internet.altel.kz | |
# APN=halebop.telia.se | |
# APN=data.tre.se | |
# APN=online.telia.se | |
# APN=internet.telenor.se | |
APN=services.telenor.se | |
# APN=internet.beeline.kz | |
# APN=internet.beeline.ru | |
# File in /etc/systemd/network/ to save networkd config to | |
NETWORKD_CONF=30-mobile.network | |
# Metric for the routes set up through this interface. Can be useful to set | |
# priorities for network interfaces when multiple of them are online and are | |
# connected to internet | |
METRIC=30 | |
# Hardcoding the modem id is not good, because it may change (often happens | |
# if you suspend/hibernate your computer). The command we do here is just a | |
# smarter version of | |
# | |
# modemId=$(mmcli --list-modems | grep -oP 'Modem/\d+' | sed 's:Modem/::') | |
# | |
# It continuosly reads the output of mmcli --monitor-modems, and takes the | |
# first modem from there. | |
echo "Waiting for any modems to come online…" | |
modemId=$( | |
(mmcli --monitor-modems &) | | |
while true; do | |
read l | |
if m=$(echo "$l" | grep -oP 'Modem/\d+'); then | |
echo "$m" | sed 's:Modem/::' | |
exit # Subshell exit | |
fi | |
done | |
) | |
print_help() { | |
cat << EOF | |
mm-connect-helper <command>|--help | |
This program is a wrapper around ModemManager's mmcli that helps connect to | |
internet through a 4G modem in settings where network is managed through | |
sysetmd-networkd (we reimplement some of NetworkManager functionality, but only | |
in a limited way). See Archwiki [1] for more info. | |
Available commands: | |
status -- print the status of the modem | |
connect -- connect and obtain IP address (this has the same effect as doing | |
connect-only and ip) | |
disconnect -- disconnect | |
connect-only -- connect without obtaining the IP address | |
ip -- obtain IP address | |
[1]: <https://wiki.archlinux.org/title/Mobile_broadband_modem> | |
Common errors: | |
libmbim.Error.Status.ServiceNotActivated -- you might be using wrong AP settings | |
EOF | |
} | |
connect() { | |
mmcli -m "$modemId" --simple-connect="apn=$APN" | |
# The following is optional, it allows checking signal level with | |
# 'mmcli -m 0 --signal-get' | |
mmcli -m "$modemId" --signal-setup=5 | |
} | |
disconnect() { | |
mmcli -m "$modemId" --simple-disconnect | |
} | |
status() { | |
mmcli -m "$modemId" --output-keyvalue | grep 'modem.generic.state' | sed 's/.*: //' | |
} | |
# Sets the ip address specified by the ModemManager | |
ip() { | |
# FIXME: Looks like sometimes the Bearer id and Modem id do not match. How | |
# do I get the correct bearer id for this command? | |
body=$(mmcli -b "$modemId") | |
field() { | |
field="$1" | |
echo "$body" | grep "$field:" | sed "s/.*$field: //" | |
} | |
address=$(field address) | |
prefix=$(field prefix) | |
gateway=$(field gateway) | |
dns=$(for i in $(field dns | sed 's:, : :'); do | |
echo "DNS=$i" | |
done) | |
( | |
cat <<EOF | |
[Match] | |
Name=$INTERFACE | |
[Network] | |
IPv6LinkLocalAddressGenerationMode=none | |
IPv6AcceptRA=false | |
$dns | |
[Address] | |
Address=$address/24 | |
RouteMetric=$METRIC | |
[Route] | |
Gateway=$gateway | |
Metric=$METRIC | |
EOF | |
) | sudo tee /etc/systemd/network/$NETWORKD_CONF | |
sudo systemctl restart systemd-networkd.service | |
} | |
remove_ip() { | |
sudo ip addr flush dev "$INTERFACE" | |
} | |
if [ "$#" -lt 1 ]; then | |
print_help | |
exit 0 | |
fi | |
case "$1" in | |
status) | |
status | |
;; | |
connect) | |
connect | |
ip | |
;; | |
disconnect) | |
disconnect | |
remove_ip | |
;; | |
connect-only) | |
connect | |
;; | |
ip) | |
ip | |
;; | |
--help|-h) | |
print_help | |
;; | |
*) | |
echo "Can't recognize the parameters" | |
print_help | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment