#!/bin/bash # # Copyright (C) 2023 Masatake YAMATO # # This file is part of util-linux. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This file is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # TS_TOPDIR="${0%/*}/../.." TS_DESC="PING and PINGv6 sockets" . "$TS_TOPDIR"/functions.sh ts_init "$*" ts_skip_nonroot . "$TS_SELF"/lsfd-functions.bash ts_check_test_command "$TS_CMD_LSFD" ts_check_test_command "$TS_HELPER_MKFDS" ts_check_prog "id" ts_check_native_byteorder ts_cd "$TS_OUTDIR" PID= FD=3 EXPR=( '(TYPE == "PING") and (FD == 3)' '(TYPE == "PINGv6") and (FD == 3)' ) FACTORY=( ping ping6 ) TYPE=( 'PING' 'PINGv6' ) COLNS=( INET INET6 ) ID=9999 range_check() { local v=$1 local min=$2 local max=$3 [[ $min -le $v && $v -le $max ]] return $? } ping_group_range_check() { local g local group_min group_max if ! read group_min group_max < /proc/sys/net/ipv4/ping_group_range; then # We can say nothing. Just allow to go ahead. return 0 fi if [[ -z "$group_min" || -z "$group_max" ]]; then # We can say nothing. Just allow to go ahead. return 0 fi for g in $(id -G); do if range_check "$g" "$group_min" "$group_max"; then return 0 fi done return 1 } ERRMSG= for i in 0 1; do ERRMSG=$("$TS_HELPER_MKFDS" -c -q "${FACTORY[$i]}" 3 id=$ID 2>&1) ERR="$?" if [[ "$ERR" == "$EACCES" ]]; then case "$ERRMSG" in *bind*) MSG="making ${TYPE[$i]} socket with specifying id is not allowed (blocked by SELinux?)" ;; *socket*) if ! ping_group_range_check; then MSG="the group(s) ($(id -G)) of the process is not in the expected range" MSG+=" [$(cat /proc/sys/net/ipv4/ping_group_range)])" else MSG="$ERRMSG" fi ;; *) MSG="$ERRMSG" ;; esac ts_skip "${MSG}" elif [[ "$ERR" != 0 ]]; then ts_skip "making ${TYPE[$i]} socket is failed ($ERR: $ERRMSG)" fi done for i in 0 1; do ts_init_subtest "${FACTORY[$i]}" { coproc MKFDS { "$TS_HELPER_MKFDS" "${FACTORY[$i]}" $FD id=$ID; } if read -r -u "${MKFDS[0]}" PID; then ${TS_CMD_LSFD} -n \ -o ASSOC,TYPE,NAME,SOCK.STATE,SOCK.TYPE,${COLNS[$i]}.LADDR,${COLNS[$i]}.RADDR,PING.ID \ -p "${PID}" -Q "${EXPR[$i]}" echo "ASSOC,TYPE,NAME,SOCK.STATE,SOCK.TYPE,${COLNS[$i]}.LADDR,${COLNS[$i]}.RADDR,PING.ID": $? echo DONE >&"${MKFDS[1]}" fi wait "${MKFDS_PID}" coproc MKFDS { "$TS_HELPER_MKFDS" "${FACTORY[$i]}" $FD id=$ID connect=0; } if read -r -u "${MKFDS[0]}" PID; then ${TS_CMD_LSFD} -n \ -o ASSOC,TYPE,NAME,SOCK.STATE,SOCK.TYPE,${COLNS[$i]}.LADDR,${COLNS[$i]}.RADDR,PING.ID \ -p "${PID}" -Q "${EXPR[$i]}" echo "ASSOC,TYPE,NAME,SOCK.STATE,SOCK.TYPE,${COLNS[$i]}.LADDR,${COLNS[$i]}.RADDR,PING.ID": $? echo DONE >&"${MKFDS[1]}" fi } > "$TS_OUTPUT" 2>&1 wait "${MKFDS_PID}" ts_finalize_subtest done ts_finalize