#!/bin/bash # push_firmware.sh # # Flash kernel image (hidden root) to Fritz!Box or Speedport. # Works on Linux (main platform) and Cygwin (inofficially). # # Copyright (c) 2007 Michael Hampicke (mike@mhampicke.de) # 2007 Alexander Kriegisch (kriegaex, ip-phone-forum.de) # 2011 extended for ALICE 7570 by MaxMuster # # Cygwin users note: # 1. There is NO guarantee whatsoever that this will work on Cygwin, even # though it does on my box (kriegaex). Provided as is. # 2. For FTP you need the 'ncftp' cygwin package (category 'net'). # 3. You need the 'ping' command from Windows (tested on XP), NOT from the # 'ping' cygwin package (please uninstall or change path so Windows # version is found first), because the cygwin version has no timeout # parameter as of today (2007-07-11). # 4. For 'hexdump' you need the 'util-linux' cygwin package (category # 'utils'). # # This program 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 program 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA function push_fw() { trap 'echo ; echo "aborted" ; exit 1' TERM INT echo echo " * You should now reboot your box ($ip)." echo " Waiting for box to shut down." echo " Tip: switch off, if reboot is not detected because it happens too quickly" echo -n " " while ping $ping_params $ip > /dev/null; do echo -n "." sleep 0.2 done echo echo echo " * No reply from box ($ip). Assuming switch-off or restart." echo " Trying to re-detect box." echo -n " " while ! ping $ping_params $ip > /dev/null; do echo -n "." sleep 0.2 done echo echo echo " * Box is back up again." echo " Initiating transfer." echo " Tip: switch off/on box several times, if FTP client cannot log in ..." echo if [ $ISALICE ]; then echo "$basename: Trying to flash an image to an \"Alice\" 7570 FritzBox." [ $(which telnet) ] || { echo "$basename: Error finding required binary \"telnet\"." ; exit 1 ;} VALUES="$(telnet_hn | telnet 2>/dev/null| grep -e '^mtd[1\|5]\|^HWRevision')" || { echo "$basename: Error trying to get values from \"Alice\" FritzBox."; exit 1; } HWR=$(echo "$VALUES" | sed -n '/^HWRev/ s/HWRevision[^0-9]*//p') [ "153" = "$HWR" ] || { echo "$basename: Error veryfing HWRevision=153 as required for \"Alice\" FritzBox. Found: HWRevision=$HWR." ; exit 1 ;} MTD=$(echo "$VALUES" | sed -n '/^mtd/ s/mtd.[^0]*// p') $(echo $MTD | tr -d '\n' | grep '0x90040000,0x907E0000' | grep -q '0x907E0000,0x90F80000') || \ { echo -e "$basename: Error veryfing mtd values for \"Alice\" box. Found values:\n$MTD" ; exit 1 ;} size=$(stat -c %s $1) let max_size=7808*1024 if [ $size -ge $max_size ]; then kernel_mtd1=$(mktemp -t freetz_mtd1_XXX) || { echo "$basename: Error creating temporary file for mtd1."; exit 1; } kernel_mtd5=$(mktemp -t freetz_mtd5_XXX) || { echo "$basename: Error creating temporary file for mtd5."; exit 1; } dd if=${arg1} of=${kernel_mtd1} bs=1k count=7808 >/dev/null 2>&1 || { echo "$basename: Error creating image part for mtd1."; exit 1; } dd if=${arg1} of=${kernel_mtd5} bs=1k skip=7808 >/dev/null 2>&1 || { echo "$basename: Error creating image part for mtd5."; exit 1; } else ISALICE=false kernel_mtd1=$1 fi else kernel_mtd1=$1 fi if [ $FOUND_NCFTP ]; then [ $ISALICE ] && ncftpput \ -d stdout \ -o doNotGetStartCWD=1,useFEAT=0,useHELP_SITE=0,useCLNT=0,useSIZE=0,useMDTM=0 \ -W "quote MEDIA FLSH" \ -Y "quote QUIT" \ -u adam2 -p adam2 \ -C $ip \ ${kernel_mtd5} mtd5 ncftpput \ -d stdout \ -o doNotGetStartCWD=1,useFEAT=0,useHELP_SITE=0,useCLNT=0,useSIZE=0,useMDTM=0 \ -W "quote MEDIA FLSH" \ -Y "quote REBOOT" \ -u adam2 -p adam2 \ -C $ip \ ${kernel_mtd1} mtd1 elif [ $FOUND_FTP ]; then ftp -n -p < [ -f ] [ ] [ -hn ]" echo "" echo "firmware firmware file to flash (mostly kernel.image)" echo "-f disable safety prompt" echo "ip bootloader IP address (default: 192.168.178.1)" echo "-hn flash image to an \"Alice/HanseNet\" Version of 7570" echo exit 1 } if [ -z "$1" ]; then usage fi img="" basename=$(basename $0) [ -e "$1" ] || { echo "$basename: $1: No such file or directory."; exit 1; } [ -f "$1" ] || { echo "$basename: $1: Not a file."; exit 1; } [ -r "$1" ] || { echo "$basename: $1: Access denied."; exit 1; } function cleanup() { [ -n "$tmpimg" -a -f "$tmpimg" ] && rm -rf "$tmpimg"; [ -n "${kernel_mtd1}" -a -f "${kernel_mtd1}" ] && rm -rf "${kernel_mtd1}"; [ -n "${kernel_mtd5}" -a -f "${kernel_mtd5}" ] && rm -rf "${kernel_mtd5}"; exit 1 } trap cleanup EXIT SIGTERM SIGINT arg1=$1 shift while [ -z "$img" ]; do if [ "$(uname -s)" == "Darwin" ]; then hexdump -n4 "$arg1" | grep -iq "81 12 ed fe" && img="$arg1" else hexdump -n4 "$arg1" | grep -iq "1281 feed" && img="$arg1" fi if [ -z "$img" ]; then if tar tf "$arg1" ./var/tmp/kernel.image > /dev/null 2>&1; then tmpimg=$(mktemp -t freetzXXX) || { echo "$basename: Error creating temporary file."; exit 1; } echo >&2 echo "Hint: file seems to be a full firmware image archive in 'tar' format" >&2 echo "containing the 'kernel.image'. Now trying to unpack and use that image." >&2 echo >&2 tar -Oxf "$arg1" ./var/tmp/kernel.image > $tmpimg arg1=$tmpimg else echo >&2 echo "Error: file is not a valid image to be written to mtd1. Please use a" >&2 echo "hidden root 'kernel.image' containing both Linux kernel and file system." >&2 echo >&2 exit 1 fi fi done while [ $# -ge 1 ]; do case "$1" in (-f) ISFORCE=true ;; (-hn) ISALICE=true ;; (-*) usage ;; (*) ip=$(echo "$1" | grep -o -e "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+") ;; esac shift done [ -z "$ip" ] && ip=192.168.178.1 ping_params="-c1 -w1" if [ "$(uname -s)" == "Darwin" ]; then ping_params="-c1 -t1" elif [ "$(uname -o)" == "Cygwin" ]; then CYGWIN=1 ping_params="-n 1 -w 500" fi if [ -n "$(which ncftp)" -a -x "$(which ncftp)" ] ; then FOUND_NCFTP=1 echo "ncftp command found." elif [ "$(uname -s)" == "Linux" -a -n "$(which ftp)" -a -x "$(which ftp)" ] ; then FOUND_FTP=1 echo "ftp command found." else echo "You have to install 'ncftp' or 'ftp' in order to use this script." exit 1 fi if [ $ISFORCE ]; then push_fw "$img" else echo echo "!!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!" echo "!!! THERE IS NO WARRANTY AT ALL !!! USE AT YOUR OWN RISK !!!" echo echo -n "Are you sure, that you want to flash " echo -en "\033[4m$img\033[0m " echo -n "directly to " echo -e "\033[4mmtd1\033[0m?" echo echo -n "proceed (y/n) " read -n 1 -s PROCEED echo if [ "$PROCEED" = "y" ]; then push_fw "$img" else echo echo "aborted" fi fi