nvrambak.bin cron backup and python decoder

Post new topic   Reply to topic    DD-WRT Forum Forum Index -> Contributions Upload
Author Message
heimi
DD-WRT Novice


Joined: 06 Dec 2012
Posts: 2

PostPosted: Thu May 01, 2014 11:44    Post subject: nvrambak.bin cron backup and python decoder Reply with quote
Hi,
I'd liked automatic backups by nvram backup which is possible in newer firmware. This command is called by ssh, cat in a local file which is compared with yesterdays file and kept if it differs. Oneliner for use in a cron.

Code:

umask 077;E=nvram;H=ddwrt;D=/var/backups/${H}_bak;A=${D}_$(date +\%F).${E};ssh $H 'B=/tmp/backup.nvram; nvram backup $B; cat $B; rm $B' 2>/dev/null >$A;B=${D}_$(date -d yesterday +\%F).${E}; if [ -f $B ]; then diff -q $A $B >/dev/null && rm $B; fi; exit 0


Remarks: cat, the output redirect and diff are working on binary files, but that's ok...

But, I'd like to track changes so I needed the textual representation of the backup. I could have used nvram show instead, but this cannot be used for restore and has problems with multiline values, so I ended up with the Python script below.
The ASCII output can easily be sorted (breaks multiline values) and than diffed with another dump for a quick overview of changes.

Code:

#!/usr/bin/env python

import struct
import os, sys, mmap

class NVRam(object):
    def __init__(self, filename, use_mmap=True):
        nvram_file = open(filename)

        if use_mmap:
            nvram_size = os.path.getsize(filename)
            self.data = mmap.mmap(nvram_file.fileno(), nvram_size, access=mmap.ACCESS_READ)
        else:
            self.data = nvram_file.read()
        #print('Read: ' + str(nvram_size));

        self.iter_position = 6
        header = self.data[0:self.iter_position]
        assert(header == 'DD-WRT')

        self.iter_position += 2

        while self.iter_position < nvram_size:
            key = self.readKey()
            value = self.readValue()

            print(key + '=' + value)

    def readValue(self):
        len = self.readWord()
        if len == 0:
            return ''
        start = self.iter_position
        self.iter_position += len
        return self.data[start:self.iter_position]

    def readKey(self):
        len = self.readByte();
        start = self.iter_position
        self.iter_position += len
        return self.data[start:self.iter_position]

    def readWord(self):
        start = self.iter_position
        self.iter_position += 2
        subset = self.data[start:self.iter_position]
        return struct.unpack('H', subset)[0]

    def readByte(self):
        start = self.iter_position
        self.iter_position += 1
        subset = self.data[start:self.iter_position]
        return struct.unpack('B', subset)[0]

def main():
    if len(sys.argv) != 2:
        print('Give DDWrt nvram file as first param.');
        exit(1)
    nvram = NVRam(sys.argv[1])


if __name__ == '__main__':
    main()
Sponsor
Display posts from previous:    Page 1 of 1
Post new topic   Reply to topic    DD-WRT Forum Forum Index -> Contributions Upload 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 cannot attach files in this forum
You cannot download files in this forum