2

Using ash, I have an IP address as a variable

IP_ADDR=192.168.1.234

I want to write the 4 bytes to a binary file and later reread them and reform the IP string.

I have the following working solution, but it seems very hacky - any better proposals?

Write:

 IP_ADDR=192.168.1.234
 serialHex=`printf '%02X' ${IP_ADDR//./ } | sed s/'\(..\)'/'\\\\x\1'/g`
 echo -n -e $serialHex | dd bs=1 of=/path/to/file seek=19 &> /dev/null

Note seek=19 indicates where in the binary file (at byte 19) to write

Read:

hexValues=`od -j 19 --read-bytes=4 --address-radix=n -t x1 /path/to/file` 
set $hexValues
for w; do echo -n "$((0x$w))."; done | sed s/.$//
Philipp
  • 4,659
  • 9
  • 48
  • 69
  • *"Note seek=19...'* -- You don't care today, but if down the road you want a C program to read this file, then you should plan ahead and align this 32-bit value on a 32-bit alignment (e.g. use byte offset 20). Multi-byte binary data should be aligned to facilitate reading into data structures, especially on RISC arches. – sawdust Jun 30 '14 at 00:05

1 Answers1

1
function ip_write {
    local FILE=$1 IP=$2 NUMS T
    IFS=. read -a NUMS <<< "$IP" 
    printf -v T '\\x%x\\x%x\\x%x\\x%x' "${NUMS[@]}"
    printf "$T" > "$FILE"
}

function ip_read {
    local FILE=$1 NUMS
    read -a NUMS < <(exec od -N4 -An -tu1 "$FILE")
    local IFS=.
    IP="${NUMS[*]}"
}

Example usage:

# Saves IP to file:
> ip_write ip.txt 10.0.0.1
> hexdump -C ip.txt
00000000  0a 00 00 01                                       |....|

# Reads IP from file:
> ip_read ip.txt
> echo "$IP"
10.0.0.1
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • This doesn't seem to work in ash. I tried to fix, but it gives me "syntax error: bad substitution" on the first printf in ip_write(). Also, how can I write at a specific position in the binary file? – Philipp Jun 25 '14 at 12:51
  • Make sure your run the script with Bash: `bash script.sh`. Please don't confuse Bash as Shell itself. Bash is a sh variant that has more features. I'm not sure how that could be done on a specific position on a binary file but that's no longer in the context of your question so perhaps it would be better to ask another question about it again. – konsolebox Jun 25 '14 at 12:59
  • Mind if I ask what version of Bash you're using? (`bash --version`) – konsolebox Jun 25 '14 at 13:01
  • I'm running (busybox's) ash. No bash. If I get the bad substitution to work, I can then pipe into dd (as in my original code) – Philipp Jun 25 '14 at 13:03
  • It would only work with Bash. Please use proper tags next time. – konsolebox Jun 25 '14 at 13:10
  • Sorry about the wrong tag. They are very close most of the time. – Philipp Jun 25 '14 at 13:14
  • I'm sorry but I would disagree on that part. Ash's supported features was even earlier than POSIX. Bash has way too many features already compared to the earlier shells. But it's ok no worries about that. – konsolebox Jun 25 '14 at 13:18