Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Generate Network Packets with C/C++

I want to generate a network packet to send over (for example) port 123 to an NTP server so I can receive and parse the returned packet. The goal is to better understand how packets are generated, read, and replied to by networked systems.

(1) Should a struct be used to generate the packet?

(2) I am not sure how to properly populate the various fields within the struct; for example, should the source and destination IP addresses be set with hex values? Or is there a more human-friendly way?

(3) Then, once the fields have been populated, can the struct be sent via send()/write() over a UDP connection to an NTP server? (or TCP, should the protocol demand it)

Is my approach reasonable? I've been reading the NTP RFC, but am still not sure what my client should be sending to the server (such as IP address; shouldn't this be taken care of by the Network Layer header?) I've modeled this NTP struct after the "transmit" example in Appendix A of RFC 5905. I apologize if my question is poorly worded or too long. Thank you in advance for any help. The code example below borrows from the example code in RFC 5905.

typedef unsigned long ipaddr;       //32 bits (4 bytes)
typedef signed char s_char;     //character type as number, -128..127
typedef unsigned int tdist;     //character type as number, 0..255
typedef unsigned long long tstamp;  //64 bits (8 bytes)
typedef unsigned long digest;       //32 bits (4 bytes)

struct Ntp {
    ipaddr  dstaddr;
    ipaddr  srcaddr;
    char    version;
    char    leap;
    char    mode;
    char    stratum;
    char    poll;
    s_char  precision;
    tdist   rootdelay;
    tdist   rootdisp;
    char    refid;
    tstamp  reftime;
    tstamp  org;
    tstamp  rec;
    tstamp  xmt;
    int     keyid;
    digest  dgst;
} Ntp;

int main()
{
    struct Ntp packet;

    //packet.dstaddr=WHAT_GOES_HERE;
    //...
    //...
    //packet.dgst=WHAT_GOES_HERE;

    return 0;
}
like image 925
shelladept Avatar asked Jun 24 '11 23:06

shelladept


1 Answers

You don't seem to have a lot of experience writing network protocols. Declaring a struct and writing it out isn't the way to go. I also point you to http://fixunix.com/ntp/257876-any-samples-ntp-sntp-client-code.html and specifically call out the following points:

  • Why do you want to roll your own as compared to run one of the existing packages?

  • One issue in writing a NTP client is getting the time right.

  • The other is not screwing up the rest of the network or putting an unreasonable load on the servers.

In any case, as discussed in the thread I pointed you to, you want to use SNTP and should take a look at the SNTP reference implementation in the ntp tarball to point the way and help you figure out what you should be doing.

like image 92
Seth Robertson Avatar answered Oct 04 '22 01:10

Seth Robertson