2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
22 eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
23 eval $(/usr/local/bin/readhash /var/ipfire/dns/settings)
33 for octet
in ${address}; do
51 address
+=( $(( n >> (8 * i) & 0xff )) )
62 # For PPPoE, the RED interface is called ppp0 (unless we use QMI)
63 if [ "${RED_TYPE}" = "PPPOE" ] && [ "${RED_DRIVER}" != "qmi_wwan" ]; then
67 # Otherwise we return RED_DEV
68 elif [ -n "${RED_DEV}" ]; then
75 if [ -n "${GREEN_DEV}" ]; then
82 if [ -n "${ORANGE_DEV}" ]; then
89 if [ -n "${BLUE_DEV}" ]; then
97 id status x1 x2
type x3 x4 x5 x6 x7 x8 x9 x10
98 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
99 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30
100 x31 x32 x33 x34 interface_mode rest
103 while IFS
="," read -r "${VARS[@]}"; do
104 # Check if the connection is enabled
105 [ "${status}" = "on" ] || continue
107 # Check if this a net-to-net connection
108 [ "${type}" = "net" ] || continue
110 # Determine the interface name
111 case "${interface_mode}" in
113 echo "${interface_mode}${id}"
116 done < /var
/ipfire
/vpn
/config
127 # OpenVPN is using all tun devices
137 network_get_address
() {
140 # Return everything before the slash
141 echo "${network%%/*}"
144 network_get_prefix
() {
147 # Consider everything after the / the prefix
148 local prefix
="${network##*/}"
150 # If the prefix is valid, return it
151 if network_prefix_is_valid
"${prefix}"; then
154 # Otherwise it might be a subnet mask
156 network_netmask_to_prefix
"${prefix}"
160 network_get_netmask
() {
163 # Consider everything after the / the netmask
164 local netmask
="${network##*/}"
166 # If we have a prefix, we need to convert
167 if network_prefix_is_valid
"${netmask}"; then
168 network_prefix_to_netmask
"${netmask}"
170 # Otherwise return what we got
176 network_prefix_is_valid
() {
179 # The prefix must be numbers only
180 if ! [[ "${prefix}" =~ ^
[0-9]+$
]]; then
184 # Must be a number between 0 and 32 (inclusive)
185 [ "${prefix}" -ge 0 -a "${prefix}" -le 32 ]
188 network_prefix_to_netmask
() {
191 # Set n with all bits set
195 (( n
<<= (32 - prefix
) ))
201 network_netmask_to_prefix
() {
207 local n
="$(ip2bin "${netmask}")"
209 while [ "${n}" -gt 0 ]; do
210 # If the highest bit is not set, we are done
211 [ "$(( n & (1 << 31) ))" -eq 0 ] && break
213 # Increment prefix & shift n
221 network_address_in_network
() {
225 # Split the network into its address & mask
226 local netaddr
="$(network_get_address "${network}")"
227 local netmask
="$(network_get_netmask "${network}")"
229 # Abort if we could not parse the network
230 if [ -z "${netaddr}" -o -z "${netmask}" ]; then
234 # Convert everything to binary
235 address
="$(ip2bin "${address}")"
236 netaddr
="$(ip2bin "${netaddr}")"
237 netmask
="$(ip2bin "${netmask}")"
239 # Ensure the network address is the first address
240 (( netaddr
&= netmask
))
243 local broadcast
=$(( netaddr | (~netmask & 0xffffffff) ))
245 # Return true if address is in the network
246 [ "${address}" -ge "${netaddr}" -a "${address}" -le "${broadcast}" ]
249 # Takes a network and list of IP addresses and will return the first IP address
250 # that is in the given network.
251 first_address_in_network
() {
257 if network_address_in_network
"${addr}" "${network}"; then
266 # Returns the first of IPFire's own IP addresses that is in any of the given networks
267 ipfire_address_in_networks
() {
271 for var
in GREEN_ADDRESS BLUE_ADDRESS ORANGE_ADDRESS
; do
272 if [ -n "${!var}" ]; then
273 addresses
+=( "${!var}" )
278 for network
in $@
; do
279 # Find and end after the first match
280 if first_address_in_network
"${network}" "${addresses[@]}"; then
290 # This function returns the pid of a dhcpcd by a given
291 # network device, if a pidfile exists.
294 local pidfile
="/var/run/dhcpcd/${device}.pid"
296 # Check if a pid file exists.
297 if [ -f "${pidfile}" ] ; then
299 # Get the pid from the file.
300 local pid
="$(<"${pidfile}")"
306 dhcpcd_is_running
() {
307 # This functions checks if a dhcpcd is running by a given pid.
311 # Check if a dhcpcd is running.
312 if [ -n "${pid}" -a -d "/proc/${pid}" ]; then
313 # Return "0" (True) if a dhcpcd is running.
317 # Return 1 (False) no dhcpcd is running.
322 # This function will start a dhcpcd on a speciefied device.
328 boot_mesg
-n "Starting dhcpcd on the ${device} interface..."
330 # Check if a dhcpcd is already running.
331 local pid
="$(dhcpcd_get_pid "${device}")"
333 if dhcpcd_is_running
"${pid}"; then
334 boot_mesg
"dhcpcd already running!" ${WARNING}
339 # Check if a DHCP hostname has been set.
340 if [ -n "${RED_DHCP_HOSTNAME}" ]; then
341 dhcp_start
+=( "-h" "${RED_DHCP_HOSTNAME}" )
344 # Tell dhcpcd to use the configured MTU
345 if [ -n "${RED_DHCP_FORCE_MTU}" ]; then
346 dhcp_start
+=( "--static" "mtu=${RED_DHCP_FORCE_MTU}" )
349 # Append any further command line options
353 /sbin
/dhcpcd
"${dhcp_start[@]}" ${device} >/dev
/null
2>&1
356 if [ "${ret}" -eq 0 ]; then
357 .
/var
/ipfire
/dhcpc
/dhcpcd
-"${device}".info
359 if [ $ip_address ]; then
362 boot_mesg
" DHCP Assigned Settings for ${device}:"
364 boot_mesg
" IP Address: $ip_address"
367 if [ -n "${RED_DHCP_HOSTNAME}" ]; then
368 boot_mesg
" Hostname: $RED_DHCP_HOSTNAME"
372 boot_mesg
" Subnet Mask: $subnet_mask"
374 boot_mesg
" Default Gateway: $routers"
376 boot_mesg
" DNS Server: $domain_name_servers"
381 boot_mesg
"DHCP for ${device} still running..."
392 # This function stops a previously started dhcpcd on a given device.
396 local leaseinfo
="/var/ipfire/dhcpc/dhcpcd-${device}.info"
398 boot_mesg
-n "Stopping dhcpcd on the ${device} interface..."
400 # Check if a dhcpcd is running.
401 local pid
="$(dhcpcd_get_pid "${device}")"
403 if ! dhcpcd_is_running
"${pid}"; then
404 boot_mesg
" Not running." ${WARNING}
410 /sbin
/dhcpcd
${dhcp_stop} ${device} &> /dev
/null
413 # Wait until dhcpd has stopped.
414 while [ -d "/proc/${pid}" ]; do
416 # repeat stop if dhcp was still running
417 /sbin
/dhcpcd
${dhcp_stop} ${device} &> /dev
/null
420 # Display console message, depended on the exit code
421 # of the stopped dhcpcd.
422 if [ "${ret}" -eq 0 ]; then
425 elif [ "${ret}" -eq 1 ]; then
426 boot_mesg
"failed to stop dhcpcd!" ${WARNING}
441 for path
in /dev
/cdc
-*; do
442 if [ -c "${path}" ]; then
443 _intf
="$(qmi_find_interface "${path}")"
445 # Check if the interface matches
446 if [ "${intf}" = "${_intf}" ]; then
457 qmi_find_interface
() {
460 qmicli
--device="${device}" --device-open-proxy --get-wwan-iface
463 qmi_enable_rawip_mode
() {
466 # Shut down the device first
467 ip link
set "${intf}" down
&>/dev
/null
469 echo "Y" > "/sys/class/net/${intf}/qmi/raw_ip"
472 qmi_configure_apn
() {
478 local username
="${4}"
479 local password
="${5}"
482 # We only support IPv4 right now
487 if [ -n "${apn}" ]; then
488 args
+=( "apn=${apn}" )
494 args
+=( "auth=${auth}" )
499 if [ -n "${username}" ]; then
500 args
+=( "username=${username}" )
504 if [ -n "${password}" ]; then
505 args
+=( "password=${password}" )
511 for arg
in ${args[@]}; do
512 if [ -n "${_args}" ]; then
515 _args
="${_args}${arg}"
518 qmicli
--device="${device}" --device-open-proxy \
519 --wds-start-network="${_args}" \
520 --client-no-release-cid &>/dev
/null
526 qmicli
--device="${device}" --device-open-proxy \
527 --wds-reset &>/dev
/null
530 # Assigns a "static" MAC address
531 qmi_assign_address
() {
535 local device
="$(qmi_find_device "${intf}")"
537 # Switch off the raw_ip mode to be able to proper
538 # assign the generated MAC address.
539 echo "N" > "/sys/class/net/${intf}/qmi/raw_ip"
543 # Generate a "random" MAC address using the device number
544 printf -v address
"02:ff:ff:ff:ff:%02x" "${device:12}"
546 # Change the MAC address
547 ip link
set "${intf}" address
"${address}"