0

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

4
Contributors
6
Replies
8
Views
5 Years
Discussion Span
Last Post by abshah
Featured Replies
  • The problem has nothing to do with 64 bit types. Values you read are not garbage, but a very valuable port definitions: [CODE]struct ofp_phy_port ports[0]; /* Port definitions. The number of ports is inferred from the length field in the header. */[/CODE] Which means, once you've [CODE]recv(connected, &features_rep, sizeof(features_rep), 0)[/CODE] … Read More

0

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.

1

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.

0

@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 !

0

@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 ?

0

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 :)

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.