Reading a router configuration file


 
Thread Tools Search this Thread
Top Forums Programming Reading a router configuration file
# 1  
Old 12-26-2012
Reading a router configuration file

Hello C specialists,

I'm trying to write a program to read out a binary configuration file produced by a router.
But the output of Name and Value is cryptic. What's going wrong?

The structure of the binary file is very simple:

struct nvram_tuple {
char *name;
char *value;
struct nvram_tuple *next;
};

Please see attached file with detailed used headers and sources.

Here the code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bcmnvram.h"
#include "typedefs.h"  

int main(int argc, char *argv[])
{
    
    
  struct nvram_tuple *srouter_defaults = NULL;
    static unsigned int defaultnum;

        FILE *in = fopen("defaults_fmk.bin", "rb");

        if (in == NULL)
        {
             printf("ERROR: Cant open file\n\n");   
             system("PAUSE");
             return 1;
        }
          
            
        defaultnum = (unsigned int)getc(in);
        defaultnum |= (unsigned int)getc(in) << 8;
        defaultnum |= (unsigned int)getc(in) << 16;
        defaultnum |= (unsigned int)getc(in) << 24;

        int i;
        srouter_defaults =
            (struct nvram_tuple *)malloc(sizeof(struct nvram_tuple) *
                         defaultnum);
                         

                     
        for (i = 0; i < defaultnum; i++) {
            unsigned int vl = (unsigned int)getc(in);
            if (vl) {
                srouter_defaults[i].name = malloc(vl + 1);
                fread(srouter_defaults[i].name, vl, 1, in);
                srouter_defaults[i].name[vl] = 0;
                vl = (unsigned int)getc(in);
                if (vl & 128) {
                    vl &= 127;
                    vl |= (unsigned int)getc(in) << 7;
                }
                srouter_defaults[i].value = malloc(vl + 1);
                fread(srouter_defaults[i].value, vl, 1, in);
                srouter_defaults[i].value[vl] = 0;
            } else {
                srouter_defaults[i].name = NULL;
                srouter_defaults[i].value = NULL;
            }
        
            printf("Parameter %d: ",i);
            printf("Name: %c ",srouter_defaults[i].name);
            printf("Value: %c ",srouter_defaults[i].value);
            printf("\n");
         }
        fclose(in);
  printf("\n\n\n\n\n");  
  system("PAUSE");    
  return 0;
}

Many thanks in forward for any hints or helps.

best regards
Frank
# 2  
Old 12-27-2012
You might just mmap() the file or fread the whole into one malloc'd buffer in one fell swoop, and then much less malloc(). If there 2,4,8 byte integers or any sort of floats in the data, write a subroutine for converting the big or little endian to the native flavor, exploiting the match if you are so lucky (LE on a LE machine).

It might be nice to present it as a simple file of name=value lines, and have a reverse conversion. Of course, the router may be fussy about the order.

Cryptic, well, that could be unicode, utf8, or ebcdic rather than the simple ascii a C programmer usually expects. Do some dump reading and see what it thinks a character string is. I guess they are null terminated or something, as there is no length provided, unless it is hidded just before the string (a common practice -- positive offsets are payload, negatve offsets are the control structure, so the 'char' pointer is to the tail character string of a variable length struct).
# 3  
Old 12-27-2012
Quote:
Originally Posted by digidax
The structure of the binary file is very simple:

struct nvram_tuple {
char *name;
char *value;
struct nvram_tuple *next;
};
Pointers have no meaning in a binary file. That cannot be the file's actual contents. They seem to be variable length fields defined by the header -- hardly simple at all.

You are printing with %c, which prints characters, rather than %s, which prints strings.
# 4  
Old 12-27-2012
This code is missing headers and cannot compile, so I can't troubleshoot it further. Hopefully %s instead of %c will do the trick.

You can also do fread() to read all four bytes at once, instead of doing getc() four times. ntohl() can convert from big-endian to little-endian if necessary.
# 5  
Old 12-28-2012
Thanks a lot, %s instead of %c is working well. So you have help me very well. Thanks again. Now I have the parameters visible.

best regards
Frank
# 6  
Old 12-28-2012
Well, pointers should be file relative, but if crudely done, there may be an arbitrary offset you need to use. They might even be negative relative to end of file. You need two spaces in the file, a linked list space and a heap of pointed to objects, but they can be intermingled:link1, char[]-1a, char[]-1b, link2, . . . . Dump reading will tell you where the strings are, if that is the nature of what their 'char' pointers point to. Remember that early compilers had no void*, so char* was it, the finest grained pointer. Perhaps if you can separate the strings and the links, you can figure out how to apply link and string pointers to the file image.

Then there is the issue of whether they are null terminated, context-known-length or a size for each is stored somewhere, like at pointer-n. More dump reading.

Last edited by DGPickett; 12-28-2012 at 01:13 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

5 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Expect script to save configuration from a router

Hy guys, My name is Alex, i am new here and I hope to find some answers. I am trying to run a expect script to telnet to a mikrotik router, run a command (export), and save the output of that commant to a file (outputfile.txt). The problem is that only part of the output is saved to... (2 Replies)
Discussion started by: axexandru
2 Replies

2. IP Networking

How to show Cisco Router Running Configuration in Third Party Application

Hey everyone, I have a few question. 1. Is it possible to display cisco 'show run' output command to the application ?? 2. And is there any ways to log in to the router instead of using telnet from telnet application??? Thanks in advance (0 Replies)
Discussion started by: franzramadhan
0 Replies

3. Shell Programming and Scripting

reading configuration files in bash. Best way?

Context: I have a random pin number generator script that reads a tab-delimited file containing a location and a count: eg., mansfield 30 tokyo 15 smithville 34It produces random PIN# in the amount specified by the number in the second column. Currently, I read the file... (7 Replies)
Discussion started by: Bubnoff
7 Replies

4. UNIX for Dummies Questions & Answers

Remote Unix printing to my WinXP works with no router. How can I make it work through my router?

I set up remote printing on a clients Unix server to my Windows XP USB printer. My USB printer is connected directly to my PC (no print server and no network input on printer). With my Win XP PC connected to my cable modem (without the router), i can do lp -dhp842c /etc/hosts and it prints. I... (7 Replies)
Discussion started by: jmhohne
7 Replies

5. Shell Programming and Scripting

Reading a value from the configuration file

Hi, I have prepared a config file in which I am declaring the value for a country such as: COUNTRY=USA Now I am trying to read the country from the config file and print a message based on the same. I have written the following code in a script and when executing the script I getting an error. ... (14 Replies)
Discussion started by: yoursdavinder
14 Replies
Login or Register to Ask a Question