Hi,
I am facing a bit of issue in writing a network software. When I try to send or receive a struct that contains a data type of 8 bytes the next sent or received struct is somehow affected. I have a few things in mind but first I wanted to confirm one thing before I get into debugging. I am using 32-bit Ubuntu 11.04 (silly me) on a 64-bit x-86 system. Does this has anything to do with the byte alignment problems ?

I am developing a controller to communicate with the Open Flow switch. The openflow protocol defines a set of specs based on which switches are built. The problem is when I try to communicate with the switch everything goes fine until I send or receive a struct that contains a 64 bit date type (uint64_t). The specific structs that are used for sending and receiving features are

struct ofp_header {
uint8_t version;    /* OFP_VERSION. */
uint8_t type;       /* One of the OFPT_ constants. */
uint16_t length;    /* Length including this ofp_header. */
uint32_t xid;       /* Transaction id associated with this packet.
                       Replies use the same id as was in the request
                       to facilitate pairing. */};   
 assert(sizeof(struct ofp_header) == 8);







/* Switch features. */
struct ofp_switch_features {
struct ofp_header header;
uint64_t datapath_id; /* Datapath unique ID. The lower 48-bits are for a MAC address, while the upper 16-bits are implementer-defined. */
uint32_t n_buffers; /* Max packets buffered at once. */
uint8_t n_tables; /* Number of tables supported by datapath. */
uint8_t pad[3]; /* Align to 64-bits. */

/* Features. */ /* Bitmap of support "ofp_capabilities". */
uint32_t capabilities; /* Bitmap of supported "ofp_action_type"s. */
uint32_t actions; 

/* Port info.*/
struct ofp_phy_port ports[0];  /* Port definitions. The number of ports is inferred from the length field in the header. */
};
assert(sizeof(struct ofp_switch_features) == 32);

The problem is when I communicate using any other structs that have data types less than 64-bit everything goes fine. When I receive features reply it shows the right values but after that if i receive any other struct it shows garbage values. Even if i receive features reply again i get garbage values. In short if at any point of code I receive features request or any other struct defined in the specs that has a data type of 64-bit the next structs receive garbage values. The code used for sending and receiving features request is as follows

////// features request and reply  ////////////

ofp_header features_req;

features_req.version=OFP_VERSION;
features_req.type=OFPT_FEATURES_REQUEST;
features_req.length= htons(sizeof features_req);
features_req.xid = htonl(rcv_hello.xid);


if (send(connected, &features_req, sizeof(features_req), 0)==-1) {
printf("Error in sending message\n");
exit(-1);
}
printf("features req sent!\n");



ofp_switch_features features_rep={0};

if (recv(connected, &features_rep, sizeof(features_rep), 0)==-1) {
printf("Error in receiving message\n");
exit(-1);
}

printf("message type : %d\n",features_rep.header.type);
printf("version : %d\n",features_rep.header.version);
printf("message length: %d\n",ntohs(features_rep.header.length));
printf("xid : %d\n",ntohl(features_rep.header.xid));
printf("buffers: %d\n",ntohl(features_rep.n_buffers));
printf("tables: %d\n",features_rep.n_tables);

thanks,
Abdullah

Recommended Answers

All 6 Replies

When you compile, do you have the option to pack your structures on a 1-byte boundary? In my old Microsoft compiler, I could use /Zp1

...otherwise, it would use the default size for every structure that went across the network.

The problem has nothing to do with 64 bit types. Values you read are not garbage, but a very valuable port definitions:

struct ofp_phy_port ports[0];  /* Port definitions. The number of ports is inferred from the length field in the header. */

Which means, once you've

recv(connected, &features_rep, sizeof(features_rep), 0)

you need to inspect features_rep.header.length , figure out how many struct ofp_phy_port follow, allocate memory for them and read those data.

@nezachem -- maaannn THANXXX A LOTTTTT! you ve really made my day I ve been going crazy over this. Thanx a lottt you are the man !

@nezachem -- Hi, It seems I still am doing something wrong :/ please look at the following details:
The size of ofp_phy_port is 48 bytes.
The size I receive in features_rep.header.length is 176 bytes. out of which 32 bytes contain features rep so the total size of ofp_phy_ports is 176-32=144. which 144/48=3 gives 3 ofp_phy_port structures and it is correct as the switch supports three ports.
Now I am allocating memory for them as follows.

if (recv(connected, &features_rep, sizeof(features_rep), 0)==-1) {
printf("Error in receiving message\n");
exit(-1);
}
int *A;
int *B;
int *C;
typedef struct ofp_phy_port ofp_phy_port;

A=(int*) malloc(sizeof(ofp_phy_port));
B= (int*)malloc(sizeof(ofp_phy_port));
C= (int*)malloc(sizeof(ofp_phy_port));
ofp_phy_port *A;
ofp_phy_port *B;
ofp_phy_port *C;
printf("port no : %d\n",A->port_no);
printf("port no : %d\n",B->port_no);
printf("port no : %d\n",C->port_no);

the struct itself for ofp_phy_port is

/* Description of a physical port */
struct ofp_phy_port {
uint16_t port_no;
uint8_t hw_addr[OFP_ETH_ALEN];
char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */
uint32_t config;
uint32_t state;
/* Bitmap of OFPPC_* flags. */
/* Bitmap of OFPPS_* flags. */
/* Bitmaps of OFPPF_* that describe features. All bits zeroed if
* unsupported or unavailable. */
uint32_t curr;
/* Current features. */
uint32_t advertised;
/* Features being advertised by the port. */
uint32_t supported;
/* Features supported by the port. */
uint32_t peer;
/* Features advertised by peer. */
};
assert(sizeof(struct ofp_phy_port) == 48);

It still isnt working out the port no that I print arent the same and the problem for the next structs still continue even if I allocate memory for the structs as u said. can u please guide me a bit more ? or Am I doing anything wrong here ?

Hey Nezachem my mistake I wasnt receiving the port definitions the switch was sending. I did that and all problems solved :) thanx a million mate :) cheers :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.