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;
}
Ntp
struct isn't padded in unpredictable ways? – Wearingecho protocol
– Momentum