Parsing a Section of Binary String Data!

Z

zoltan

Hi,
The scenario is like this :


struct ns_rr {

const u_char* rdata;
};

The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

I want to parse the rdata section and obtain the individual string
fields as shown above. Can anyone suggest an efficient method? Are
these strings terminiated by '\0' within the rdata section?


Thanks and Regards,

Timmy Jose.
 
K

Keith Thompson

zoltan said:
Hi,
The scenario is like this :


struct ns_rr {

const u_char* rdata;
};

Is u_char a typedef for unsigned char? (If so, just using "unsigned
char" would be a lot clearer.)
The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

No, the rdata member (not field) is a pointer; it doesn't contain
anything. Are you talking about something that rdata points to?
I want to parse the rdata section and obtain the individual string
fields as shown above. Can anyone suggest an efficient method? Are
these strings terminiated by '\0' within the rdata section?

You want to parse the rdata section of what? Is this coming from a
file? Are we supposed to know what an "rdata section" is? A Google
search indicates that there is such a thing (or perhaps more than one
such things), but it's not part of the C programming language.
 
D

dotnetdotcn

zoltan said:
Hi,
The scenario is like this :


struct ns_rr {

const u_char* rdata;
};

The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

I want to parse the rdata section and obtain the individual string
fields as shown above. Can anyone suggest an efficient method? Are
these strings terminiated by '\0' within the rdata section?


Thanks and Regards,

Timmy Jose.

look at this:
struct ns_rr * a;
puts(a->rdata->flags);
 
K

Keith Thompson

Keith Thompson said:
Is u_char a typedef for unsigned char? (If so, just using "unsigned
char" would be a lot clearer.)


No, the rdata member (not field) is a pointer; it doesn't contain
anything. Are you talking about something that rdata points to?
[...]

I realize that my assumption that u_char is a typedef for unsigned
char may have been unwarranted. If u_char is a typedef for a struct
type that contains the flags, services, regexp, and replacement
members, the question makes a bit more sense. (Though the name
"u_char" certainly doesn't point in that direction.)

But it would still be very helful to show us the actual declarations
and a better idea of what you want to do with them.
 
Z

zoltan

Keith said:
Is u_char a typedef for unsigned char? (If so, just using "unsigned
char" would be a lot clearer.)


No, the rdata member (not field) is a pointer; it doesn't contain
anything. Are you talking about something that rdata points to?


You want to parse the rdata section of what? Is this coming from a
file? Are we supposed to know what an "rdata section" is? A Google
search indicates that there is such a thing (or perhaps more than one
such things), but it's not part of the C programming language.


ns_rr is a structure which defines the type of the Resource Record (RR)
as used for DNS Queries. The structure is defined in <arpa/nameser.h> .

The rdata "member" points to memory where the various mentioned fields
are stored. This is because the contents of rdata depend on the type of
Resource Record.

So suppose I have a structure of this type ns_rr, how can I extract the
individual fields of the rdata member? Simple query.
 
Z

zoltan

look at this:
struct ns_rr * a;
puts(a->rdata->flags);

The problem is this :

ns_rr is the Standard type which is used to store the data.

I know that the various fields ( flag, services etc) are in the rdata
member. So to extract them, I define my own structure like this :

struct NAPTR
{

char * flags;
char * services;
char * regexp;
char * replacement;
};

So the compiler has no idea that there is a field called "flags" inside
the rdata member!!! That is the trouble... Any ideas?
 
K

Keith Thompson

zoltan said:
Keith Thompson wrote: [...]
You want to parse the rdata section of what? Is this coming from a
file? Are we supposed to know what an "rdata section" is? A Google
search indicates that there is such a thing (or perhaps more than one
such things), but it's not part of the C programming language.

ns_rr is a structure which defines the type of the Resource Record (RR)
as used for DNS Queries. The structure is defined in <arpa/nameser.h> .

You need to ask in a system-specific newsgroup, (perhaps
comp.unix.programmer).
 
N

Nick Keighley

you tell me.

The problem is this :

ns_rr is the Standard type which is used to store the data.

I know that the various fields ( flag, services etc) are in the rdata
member. So to extract them, I define my own structure like this :

struct NAPTR
{

char * flags;
char * services;
char * regexp;
char * replacement;
};

So the compiler has no idea that there is a field called "flags" inside
the rdata member!!! That is the trouble... Any ideas?

I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't do
what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures used.
 
P

Pedro Graca

zoltan said:
Hi,
The scenario is like this :


struct ns_rr {

const u_char* rdata;
};

What is u_char?
I'll assume it's a struct with (possibly among others) these members:
The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

I want to parse the rdata section and obtain the individual string
fields as shown above. Can anyone suggest an efficient method? Are
these strings terminiated by '\0' within the rdata section?

I have absolutely no idea. If they are, you can use standard string
handling functions to mess with them; if they are not you should take
extra care when dealing with those members.

Here's a short program that tries to put together the information you
provided and uses the individual members of `rdata`.


#include <stdio.h>

struct u_char { /* bad choice of name */
char * flags;
char * services;
char * regexp;
char * replacement;
};

struct ns_rr {
const struct u_char * rdata;
};

int main(void) {
struct u_char dummy = {"flags", "services", "regexp", "replacement"};
struct ns_rr x;

x.rdata = &dummy;
printf("x.rdata->flags is '%s'.\n", x.rdata->flags);
printf("x.rdata->services is '%s'.\n", x.rdata->services);
printf("x.rdata->regexp is '%s'.\n", x.rdata->regexp);
printf("x.rdata->replacement is '%s'.\n", x.rdata->replacement);

return 0;
}
 
Z

zoltan

Nick said:
you tell me.



I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't do
what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures used.

Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?

I hope that is clear enough to elicit a suggestion or a positive
response in the least!

Regards,

Timmy Jose.
 
Z

zoltan

Pedro said:
What is u_char?
I'll assume it's a struct with (possibly among others) these members:


I have absolutely no idea. If they are, you can use standard string
handling functions to mess with them; if they are not you should take
extra care when dealing with those members.

Here's a short program that tries to put together the information you
provided and uses the individual members of `rdata`.


#include <stdio.h>

struct u_char { /* bad choice of name */
char * flags;
char * services;
char * regexp;
char * replacement;
};

struct ns_rr {
const struct u_char * rdata;
};

int main(void) {
struct u_char dummy = {"flags", "services", "regexp", "replacement"};
struct ns_rr x;

x.rdata = &dummy;
printf("x.rdata->flags is '%s'.\n", x.rdata->flags);
printf("x.rdata->services is '%s'.\n", x.rdata->services);
printf("x.rdata->regexp is '%s'.\n", x.rdata->regexp);
printf("x.rdata->replacement is '%s'.\n", x.rdata->replacement);

return 0;
}

Hi Pedro,
Thanks for the effort taken to write the program! I'm afraid that it
doesn't quite answer my question....

u_char is unsigned char ( I found it used in Solaris systems... yes, I
know those people are weird!)

so it is just a character pointer basically....

I have explained the whole problem in clearer terms in the reply to the
previous post. Kindly see that!

Regards,

Timmy Jose.
 
P

pemo

zoltan said:
Nick said:
you tell me.



I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't
do what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures
used.

Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be
processed resides in RRs ( Resource Records). The header
<arpa/nameser.h> contains the following structure to store the data
of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the
respective fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?


I hope that is clear enough to elicit a suggestion or a positive
response in the least!


Can't say that I've really seen anything other than people trying to help
you here - and asking you to clarify what it is that's the problem.

But for a suggestion ...

Googling for

priority weight port SRV regexp

turned up

http://www.cisco.com/en/US/products...ducts_user_guide_chapter09186a0080155722.html


This in turn contains stuff on NAPTR

Which gives some examples.

Then googling for

parse NAPTR

Turns up what could be a useful page for you - see these on
http://www.asterisk.org/doxygen/enum_8c.html

static int parse_ie (char *data, int maxdatalen, char *src, int srclen)
Parse NAPTR record information elements.

static int parse_naptr (char *dst, int dstsize, char *tech, int techsize,
char *answer, int len, char *naptrinput) Parse DNS NAPTR record used in
ENUM ---.


Does that help??
 
Z

zoltan

pemo said:
zoltan said:
Nick said:
zoltan wrote:
(e-mail address removed) wrote:
zoltan wrote:

The scenario is like this :

struct ns_rr {
const u_char* rdata;
};

The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

I want to parse the rdata section and obtain the individual
string fields as shown above. Can anyone suggest an efficient
method? Are these strings terminiated by '\0' within the rdata
section?

you tell me.

<snip>

The problem is this :

ns_rr is the Standard type which is used to store the data.

I know that the various fields ( flag, services etc) are in the
rdata member. So to extract them, I define my own structure like
this :

struct NAPTR
{

char * flags;
char * services;
char * regexp;
char * replacement;
};

So the compiler has no idea that there is a field called "flags"
inside the rdata member!!! That is the trouble... Any ideas?

I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't
do what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures
used.

Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be
processed resides in RRs ( Resource Records). The header
<arpa/nameser.h> contains the following structure to store the data
of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the
respective fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?


I hope that is clear enough to elicit a suggestion or a positive
response in the least!


Can't say that I've really seen anything other than people trying to help
you here - and asking you to clarify what it is that's the problem.

But for a suggestion ...

Googling for

priority weight port SRV regexp

turned up

http://www.cisco.com/en/US/products...ducts_user_guide_chapter09186a0080155722.html


This in turn contains stuff on NAPTR

Which gives some examples.

Then googling for

parse NAPTR

Turns up what could be a useful page for you - see these on
http://www.asterisk.org/doxygen/enum_8c.html

static int parse_ie (char *data, int maxdatalen, char *src, int srclen)
Parse NAPTR record information elements.

static int parse_naptr (char *dst, int dstsize, char *tech, int techsize,
char *answer, int len, char *naptrinput) Parse DNS NAPTR record used in
ENUM ---.


Does that help??

Hi,
The second link was quite helpful. It at least gives some idea
about the alternatives. Thanks for the Googling.

Regards,

Timmy Jose.
 
P

Pedro Graca

zoltan said:
Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

It depends on how the data in rdata is structured.

rdata is a pointer to unsigned char, hiding the real data it holds.
You have to come up with a way to get that data into suitable C objects.

I didn't follow the links posted else-thread (where probably the rdata
structure is documented) so I'll just make it up:


rdata = "\x01\x02\x03\x04" /* order (32-bit unsigned int) */
"\x05\x06\x07\x08" /* preference (32-bit unsigned int) */
"\x41\x00" /* flags (NUL terminated string) */
"\x54\x43\x50\x00" /* services (NUL terminated string) */
"\x28\x2E\x2A\x29\x00" /* regexp (NUL terminated string) */
"\x3d\x00"; /* replacement (NUL terminated string) */

struct NAPTR data;
/* assuming `unsigned int` bit representation is LSB first */
data.order = rdata[0] + (rdata[1]<<8) + (rdata[2]<<16) + (rdata[3]<<24);
data.preference = rdata[4] + (rdata[5]<<8) + (rdata[6]<<16) + (rdata[7]<<24);
data.flags = rdata+8;
data.services = data.flags + strlen(data.flags) + 1;
data.regexp = data.services + strlen(data.services) + 1;
data.replacement = data.regexp + strlen(data.regexp) + 1;
 
P

Pedro Graca

Pedro Graca failed to state the assumptions:
I'll just make it up:

Assuming CHAR_BIT == 8
and sizeof(unsigned int) == 4

assert(CHAR_BIT == 8);
assert(sizeof(unsigned int) == 4);
rdata = "\x01\x02\x03\x04" /* order (32-bit unsigned int) */
[snip]
 
N

Nick Keighley

zoltan said:
Nick said:
you tell me.



I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't do
what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures used.

Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?

I hope that is clear enough to elicit a suggestion or a positive
response in the least!

I gather uchar_t is an unsigned char. How about:-

struct NAPTR *naptr;
ns_rr ns_rr_data;

/* load somehow ns_rr_data */

naptr = (struct NAPTR*)ns_rr_data.rdata;
printf ("services = \"%s\"\n", naptr->services);

this assumes your structure is laid out in the same way as the data in
ns_rr.
Check if they define something like your struct NAPTR and use that.
 
Z

zoltan

Nick said:
zoltan said:
Nick said:
zoltan wrote:
(e-mail address removed) wrote:
zoltan wrote:
The scenario is like this :

struct ns_rr {
const u_char* rdata;
};

The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

I want to parse the rdata section and obtain the individual string
fields as shown above. Can anyone suggest an efficient method? Are
these strings terminiated by '\0' within the rdata section?

you tell me.

<snip>

The problem is this :

ns_rr is the Standard type which is used to store the data.

I know that the various fields ( flag, services etc) are in the rdata
member. So to extract them, I define my own structure like this :

struct NAPTR
{

char * flags;
char * services;
char * regexp;
char * replacement;
};

So the compiler has no idea that there is a field called "flags" inside
the rdata member!!! That is the trouble... Any ideas?

I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't do
what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures used.

Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?

I hope that is clear enough to elicit a suggestion or a positive
response in the least!

I gather uchar_t is an unsigned char. How about:-

struct NAPTR *naptr;
ns_rr ns_rr_data;

/* load somehow ns_rr_data */

naptr = (struct NAPTR*)ns_rr_data.rdata;
printf ("services = \"%s\"\n", naptr->services);

this assumes your structure is laid out in the same way as the data in
ns_rr.
Check if they define something like your struct NAPTR and use that.

Yes Nick, the data is laid out in the pattern defined in the
corresponding RFC - RFC 2915. So it can be safely assumed that the
data is laid out in the same way in rdata.

This actually seems like a very good option. The testing machine is
down, so I will have to wait a bit to try it out... but thanks so much
for the suggestion!! Will post bacl here with the results...

Thanks and regards,

Timmy Jose.
 
Z

zoltan

Nick said:
zoltan said:
Nick said:
zoltan wrote:
(e-mail address removed) wrote:
zoltan wrote:
The scenario is like this :

struct ns_rr {
const u_char* rdata;
};

The rdata field contains some fields such as :

char * flags;
char * services;
char * regexp;
char * replacement;

I want to parse the rdata section and obtain the individual string
fields as shown above. Can anyone suggest an efficient method? Are
these strings terminiated by '\0' within the rdata section?

you tell me.

<snip>

The problem is this :

ns_rr is the Standard type which is used to store the data.

I know that the various fields ( flag, services etc) are in the rdata
member. So to extract them, I define my own structure like this :

struct NAPTR
{

char * flags;
char * services;
char * regexp;
char * replacement;
};

So the compiler has no idea that there is a field called "flags" inside
the rdata member!!! That is the trouble... Any ideas?

I've read your posts and I still havn't a clue what you're talking
about.
Could you post a small, complete, compilable example. If it doesn't do
what you want then explain what you expected it to do and what it
actually does. Please include definitions of all data structures used.

Okay, Here are the actual structures :

I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?

I hope that is clear enough to elicit a suggestion or a positive
response in the least!

I gather uchar_t is an unsigned char. How about:-

struct NAPTR *naptr;
ns_rr ns_rr_data;

/* load somehow ns_rr_data */

naptr = (struct NAPTR*)ns_rr_data.rdata;
printf ("services = \"%s\"\n", naptr->services);

this assumes your structure is laid out in the same way as the data in
ns_rr.
Check if they define something like your struct NAPTR and use that.


Hi,
To test the hypothesis, I wrote this sample program.... Can u tell
me why it does not work? The program segment faults... ( after the
printf("%s",record.rdata); statement).


// Program to test the rdata parsing capability.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <malloc.h>

struct NAPTR
{

unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};

struct nsrr
{

char name[255];
unsigned type;
unsigned class;
unsigned ttl;
unsigned rdlength;
char *rdata;
};


int main(void)
{

struct NAPTR *naptr;
struct nsrr record;


record.rdata=(char*)malloc(1024);

strcpy(record.name,"www.foo.com");
record.type=1;
record.class=1;
record.ttl=8640;
strcpy(record.rdata,"100 10 s sip+e2u !http://[^/:](.*)!\1!i
www.foo.com");
record.rdlength=sizeof(record.rdata);

printf("%s",record.rdata);

naptr=(struct NAPTR*)(record.rdata);

printf("\nThe Record contents are : ");

printf("%s",naptr->flags);
printf("\n%s",naptr->services);
printf("\n%s",naptr->regexp);
printf("\n%s",naptr->replacement);
return 0;
}

Thanks and Regards,

Timmy Jose.
 
N

Nick Keighley

zoltan said:
I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?

I hope that is clear enough to elicit a suggestion or a positive
response in the least!

I gather uchar_t is an unsigned char. How about:-

struct NAPTR *naptr;
ns_rr ns_rr_data;

/* load somehow ns_rr_data */

naptr = (struct NAPTR*)ns_rr_data.rdata;
printf ("services = \"%s\"\n", naptr->services);

this assumes your structure is laid out in the same way as the data in
ns_rr.
Check if they define something like your struct NAPTR and use that.

To test the hypothesis, I wrote this sample program.... Can u tell
me why it does not work? The program segment faults... ( after the
printf("%s",record.rdata); statement).


// Program to test the rdata parsing capability.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <malloc.h>

struct NAPTR
{

unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};

struct nsrr
{

char name[255];
unsigned type;
unsigned class;
unsigned ttl;
unsigned rdlength;
char *rdata;
};


int main(void)
{

struct NAPTR *naptr;
struct nsrr record;

record.rdata=(char*)malloc(1024);

cast not needed. Test for malloc failure
strcpy(record.name,"www.foo.com");


record.type=1;
record.class=1;
record.ttl=8640;
strcpy(record.rdata,"100 10 s sip+e2u !http://[^/:](.*)!\1!i
www.foo.com");
record.rdlength=sizeof(record.rdata);

try your debugger (I can't believe I said that...). The rdata doesn't
seem
to be in the same format as NAPTR...

printf("%s",record.rdata);

naptr=(struct NAPTR*)(record.rdata);

this trick is dangerous if the data is not formatted as struct NAPTR.
and yours isn't
 
Z

zoltan

Nick said:
zoltan said:
Nick said:
zoltan wrote:
Nick Keighley wrote:
zoltan wrote:
(e-mail address removed) wrote:
zoltan wrote:
I am supposed to implement a DNS Query. The Information to be processed
resides in RRs ( Resource Records). The header <arpa/nameser.h>
contains the following structure to store the data of these RRs as :

typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uchar_t *rdata;
} ns_rr;

Now, the rdata part can have several fields depending on the specific
type of Record.
For instance, the SRV type has only the following fields : priority,
weight, port ( all of unsigned int type) and a target string ( the
hostname).

For my requirement, I have to use the data stored in a NAPTR record.
The "rdata" contains the following fields for this type of record :

order, preference ( unsigned int) and
flags, services, regexp and replacement ( all of type char *).

Now, because the definition of the rdata in the ns_rr structure is
generic, I have defined ( as I need to ) a structure as follows, to
store the actual data :

struct NAPTR
{
unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};


So my question is this : How can I extract the string fields from the
rdata portion of the ns_rr structure and store them into the respective
fields in my user-defined structure?

The integer fields ( order and preference ) are easy enough, being of
fixed size. What about the strings which can be of variable size?

I hope that is clear enough to elicit a suggestion or a positive
response in the least!

I gather uchar_t is an unsigned char. How about:-

struct NAPTR *naptr;
ns_rr ns_rr_data;

/* load somehow ns_rr_data */

naptr = (struct NAPTR*)ns_rr_data.rdata;
printf ("services = \"%s\"\n", naptr->services);

this assumes your structure is laid out in the same way as the data in
ns_rr.
Check if they define something like your struct NAPTR and use that.

To test the hypothesis, I wrote this sample program.... Can u tell
me why it does not work? The program segment faults... ( after the
printf("%s",record.rdata); statement).


// Program to test the rdata parsing capability.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <malloc.h>

struct NAPTR
{

unsigned int order;
unsigned int preference;
char * flags;
char * services;
char * regexp;
char * replacement;
};

struct nsrr
{

char name[255];
unsigned type;
unsigned class;
unsigned ttl;
unsigned rdlength;
char *rdata;
};


int main(void)
{

struct NAPTR *naptr;
struct nsrr record;

record.rdata=(char*)malloc(1024);

cast not needed. Test for malloc failure
strcpy(record.name,"www.foo.com");


record.type=1;
record.class=1;
record.ttl=8640;
strcpy(record.rdata,"100 10 s sip+e2u !http://[^/:](.*)!\1!i
www.foo.com");
record.rdlength=sizeof(record.rdata);

try your debugger (I can't believe I said that...). The rdata doesn't
seem
to be in the same format as NAPTR...

printf("%s",record.rdata);

naptr=(struct NAPTR*)(record.rdata);

this trick is dangerous if the data is not formatted as struct NAPTR.
and yours isn't
printf("\nThe Record contents are : ");

printf("%s",naptr->flags);
printf("\n%s",naptr->services);
printf("\n%s",naptr->regexp);
printf("\n%s",naptr->replacement);
return 0;
}

I suppose u are referring to the fact that I havent' mentioned anything
about the Domain Name, class etc.

The structure of the NAPTR record acc to RFC 2915 is :

Domain TTL Type Class Order Preference Flags Services Regexp
Replacement. The ns_rr structure defined is <arpa/nameser.h> actually
has separate fields for Domain, TTL, Type and Class. These are
considered as the Header. The remaining fields form the rdata portion.

I just require to extract the fields in the rdata section, so I wrote
this simple program. How is the RDATA section not the same as the one
in the example?

Thanks and Regards,

Timmy Jose.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top