Skip to content

Instantly share code, notes, and snippets.

@gnull
Last active May 7, 2023 00:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnull/8728d7498bb6f61aa5bfa85d14de9152 to your computer and use it in GitHub Desktop.
Save gnull/8728d7498bb6f61aa5bfa85d14de9152 to your computer and use it in GitHub Desktop.
#!/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