Question

Im stuck with a problem of reading bytes in my C tcp socket server which receives request from a python client. I have the following struct as my receive template

struct ofp_connect {
uint16_t wildcards;                /* identifies ports to use below */
uint16_t num_components;           

uint8_t  pad[4];                   /* Align to 64 bits */

uint16_t in_port[0];               
uint16_t out_port[0];           

struct ofp_tdm_port in_tport[0];   
struct ofp_tdm_port out_tport[0];

struct ofp_wave_port in_wport[0];  
struct ofp_wave_port out_wport[0];

};
OFP_ASSERT(sizeof(struct ofp_connect) == 8);

I can read the first two 32 bit fields properly but my problem is the in_port[0] after the pad field that seems to be wrong. The way its currently being read is

uint16_t portwin, portwout, * wportIN;
wportIN =  (uint16_t*)&cflow_mod->connect.in_port; //where cflow_mod is the main struct which encompasses connect struct template described above 
memcpy(&portwin, wportIN, sizeof(portwin) );
DBG("inport:%d:\n", ntohs(portwin));

unfortunately this doesnt give me the expected inport number. I can check in wireshark that the client is sending the right packet format but I feel the way I read the in/out port is wrong. Or is it because of the way python sends the data? Can you provide some advice on where and why im going wrong? Thanks in advance.

Was it helpful?

Solution

The declaration of struct ofp_connect violates the following clause of the ISO C standard:

6.7.2.1 Structure and union specifiers ... 18 As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.

Note that in your case in_port and out_port should have been declared as in_port[] and out_port[] to take advantage of the clause above in which case you would have two flexible array membes, which is prohibited by the above clause. The zero-length array declaration is a convention adopted by many compilers (including gcc, for example) which has the same semantics but in your case, both in_port and out_port share the same space (essentially whatever bytes follow the ofp_connect structure). Moreover, for this to work, you have to allocate some space after the structure for the flexible array members. Since, as you said, struct connect is part of a larger structure, accessing in_port returns the 'value' stored in the containing structure's member following the connect sub-struct

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top