Parental control time limit for kids

Post new topic   Reply to topic    DD-WRT Forum Index -> General Questions
Goto page Previous  1, 2
Author Message
pernils
DD-WRT Novice


Joined: 19 Dec 2021
Posts: 4

PostPosted: Fri Jan 07, 2022 6:10    Post subject: Reply with quote
After some more hours .... ( I have not yet tested it my self)

Code:


#!/bin/sh -x
# set +x  remove debug
# set -x enable debug
# https://www.shellcheck.net/  own reminder
#
#      Session time quota v0.1 by Pernils Snygg 2022-01-07
#
#   The script is to limit the total time used by a device per day.
# This is achieved by checking the arp table for the device.
#     (arp table is flushed every 45 sec by default)
# If the device is found the counter increase with the time elapsed since last time the device was found.
# The client and time quota can be edit with these variables.

client_default=192.168.1.127               # default ip or mac (in format: 00:00:00:aa:aa)
# limits is entered in minutes
mon_lim=70      # Monday
tue_lim=70      # Thuesday
wen_lim=5         # ...
thu_lim=5
fri_lim=150
sat_lim=150
sun_lim=5

# Install :
# In dd-wrt web interface goto   Administration -> Command, and copy and paste the script
# and click the button   Save startup  or  Save Custom.

#
# Under Administration -> Management ad a cron job pointing to the script.
# Save startup button : /tmp/.rc_startup
# Save custom button  : /tmp/.rc_custom
#
#   The script can be called by arguments : client monday tuesday ..
#
# Example of cronscript executed every 5 minutes, remember cron must be called by root
# (60 minutes mon-wen and 120 the rest of the week)
#
# */5 * * * * root /tmp/.rc_starup 192.168.1.254 60 60 60 120 120 120 1
#
# */5 * * * * root /tmp/.rc_starup 8a:fe:60:70:9f:c7 60 60 60 120 120 120 1
#
# above the same time quota but with mac address
# You can add as many clients you need but clients who never shuts off like tablets will
# by there broadcast trigger the counter mechanism even not in use.
#
# Have a idea to fix this but future will tell if it will be implemented.
#
# The counters is reset at midnight or if the router is rebooted.
#
#
access_log=/tmp/lars_access                  # Name of the access_log file
u_time_default=0            # default start value for users used time in seconds [$u_time]


# The same for ip as mac address
delete_rules() {
nr=$(iptables -S FORWARD |grep -wn "$s_client" | cut -d: -f1 | head -n 1)

   while [ "$nr" -gt 1 ]; do
      nr=$((nr - 1))
      iptables -D FORWARD $nr
      nr=$(iptables -S FORWARD |grep -wn "$s_client" | cut -d: -f1 | head -n 1)
      echo "$nr"
   done
#iptables -S FORWARD
}

drop_mac() {
#iptables -I FORWARD -m mac --mac-source 08:00:27:9B:BB:C5 -j DROP   
  iptables -I FORWARD -m mac --mac-source $s_client -j DROP   
  echo drop
}

accept_mac() {
  iptables -I FORWARD -m mac --mac-source $s_client -j DROP   
  echo drop
}


drop_ip() {
   iptables -I FORWARD -d $s_client -j DROP
  echo drop
}
accept_ip() {
#   iptables -I FORWARD -d $s_client -j ACCEPT
   echo accept
}

drop_client() {
   delete_rules
if echo "$s_client" |grep : ; then # : = mac address
   drop_mac
#      echo dropping
   else
#      echo tt   
   drop_ip
   fi
}

accept_client() {
   delete_rules
}



write_log() {    #$s_client $s_date $s_time $u_time
   echo write log : "$1" "$2" "$3" "$4"
   if grep -w "$s_client" "$access_log"; then
      sed -i "/$1/c ${1} ${2} ${3} ${4}" $access_log
      echo gick
   else
      echo "$1" "$2" "$3" "$4" >>$access_log  # no entry = append access_log
   fi

# get clients session linenum entry
#   lineNum="$(grep -n -m 1 "$s_client" "$access_log" | cut -d: -f1)"
 
# client have an entry already in the access_log, (lineNum is set)
#   if [ -z "$lineNum" ]; then         
#    sed '1 c$s_client $s_date $s_time $u_time' $access_log > ${access_log}.tmp
#     cat ${access_log}.tmp > $access_log      # possible bug if race condition
 #   rm ${access_log}.tmp                           # the  { } is to mark where varibale name stops
 # else
 #   echo "$s_client" "$s_date" "$s_time" "$u_time" >>$access_log  # no entry = append access_log
 # fi

}



read_session_log() {
   # create new session_file if missing
   if [ ! -f $access_log ]; then touch $access_log; fi                        

# read client session entry from access_log, delimiter is ' '
#    IFS=' ' read -r s_client s_date s_time u_time <<<`grep -w $client $access_log`

if tmp=$(grep -w "$s_client" "$access_log"); then                               
  s_client=$(echo "$tmp" |cut -f 1 -d ' ')                                     
  s_date=$(echo "$tmp" |cut -f 2 -d ' ')                         
  s_time=$(echo "$tmp" |cut -f 3 -d ' ')                                       
  u_time=$(echo "$tmp" |cut -f 4 -d ' ')                                       
                                                                               
        # client not found in the access log                                   
  else                                                                         
    s_date=$(date +"%F")                 # current date                         
    s_time=$(date +"%T")                 # current time                         
    u_time=$u_time_default       # default user time                       
  fi 


}




validate_session() {
   case $(date +%u) in          # get maxlimit for current day * 60 for second
      1) maxlimits=$((mon_lim * 60))   # minute * 60 for second
      ;;
      2) maxlimits=$((tue_lim * 60))
      ;;
      3) maxlimits=$((wen_lim * 60))
      ;;
      4) maxlimits=$((thu_lim * 60))
      ;;
      5) maxlimits=$((fri_lim * 60))
      ;;
      6) maxlimits=$((sat_lim * 60))
      ;;
      7) maxlimits=$((sun_lim * 60))
   esac                               


# rester counter if passing midnight
   if [ $(date -d $(date +"%F") +"%Y%m%d") -gt $(date -d $s_date +"%Y%m%d") ]; then
     u_time=$u_time_default
     s_time=$(date +"%T")
  fi 

   if [ $u_time -le $maxlimits ]; then      # limits have not reach

      TIME1=$(date +"%T")                           # current time stamp
      TIME2=$s_time                                    # last checked time stamp

     # Convert the times to seconds from the Epoch
      SEC1=$(date +%s -d "${TIME1}")
      SEC2=$(date +%s -d "${TIME2}")



      # Use expr to do the math, current time - last checked time + users used time
      DIFFSEC=$(( SEC1 - SEC2 + u_time))  #u_time is in seconds
#    DIFFMIN=$(( $DIFFSEC / 60 ))                                   
                                                                               
#       DIFF=`date +%H:%M:%S -d @${DIFFSEC}`    # format to hh:mm:ss           
                                                                               
        write_log "$s_client" "$(date +"%F %T")" $DIFFSEC

      accept_client          # remove rules
   else
      drop_client            # dropin client ip / mac   (user have consumed its limits)
   fi
}


# **************************
#      MAIN
# **************************
s_client=$client_default
if [ "$1" ]; then s_client=$1; fi  # sets arguments if exists
if [ "$2" ]; then mon_lim=$2; fi
if [ "$3" ]; then tue_lim=$3; fi
if [ "$4" ]; then wen_lim=$4; fi
if [ "$5" ]; then thu_lim=$5; fi
if [ "$6" ]; then fri_lim=$6; fi
if [ "$7" ]; then sat_lim=$7; fi
if [ "$8" ]; then sun_lim=$8; fi
if [ "$9" ]; then c_reset_at=$9; fi  # counter resets at

if arp | grep -w "$s_client"; then      # see if $s_client exist in arp table

  read_session_log
  validate_session      

#  cat $access_log
fi


[/code]
Sponsor
70p4z
DD-WRT Novice


Joined: 20 Jul 2023
Posts: 1

PostPosted: Thu Jul 20, 2023 16:16    Post subject: Contribution Reply with quote
Dear all,
I've read this topic delightfully because I ran into the same issue.
I tried to make it easier to configure it.
Here is a gist that works on my Netgear R7000.

https://gist.github.com/70p4z/78dceb382b7216f0e815e81da6bb7fcb

I've included a threshold based on packet (but it could/should be done on bytes instead) to allow for an idle laptop not to account for children triggered traffic (windows update background, etc)

I hope it may be of use, even if I quite unearthed the topic!
Goto page Previous  1, 2 Display posts from previous:    Page 2 of 2
Post new topic   Reply to topic    DD-WRT Forum Index -> General Questions All times are GMT

Navigation

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum