Appending raw bytes to the back of packet_out frame in Trema

36 views
Skip to first unread message

Sadiq Yakasai

unread,
Jan 20, 2015, 2:08:47 PM1/20/15
to trem...@googlegroups.com
Hello,

I want to create an ethernet frame header and then append raw bytes to the back of this frame. Then generate my packet_out message and send to the OF switch. I am using original Trema (OF 1.0). I am having problems. Can someone help out please. The issue is I am not able to see my received bytes (from socket) - the ethernet header is constructed fine and seen on the wireshark trace.

See below:

    unsigned char *buf;
    buf = (unsigned char *) calloc (1500);

    int rxBytes = read(sfd, buf, 1500); // read raw bytes from the socket (which is successful)

    buffer *frame =  alloc_buffer_with_length( rxBytes + sizeof(ether_header_t) );
    ether_header_t *ether = append_back_buffer( frame, sizeof(ether_header_t) );
       
    buf = (unsigned char *)append_back_buffer( frame, (size_t)rxBytes );

    memcpy (ether->macsa, trema_macsa, ETH_ADDRLEN);
    memcpy (ether->macda, pae_group_addr, ETH_ADDRLEN);
    ether->type = htons( ETH_ETHTYPE_8021X );
   
    openflow_actions *actions = create_actions();
    append_action_output( actions, OFPP_FLOOD, UINT16_MAX );
    fill_ether_padding( frame );
       
    buffer *packet_out = create_packet_out( get_transaction_id(), UINT32_MAX, OFPP_NONE, actions, frame);

    int ret = send_openflow_message( 1, packet_out);

++++++++++++++++

This is what I see after the ethernet header: the zeros are added by fill_ether_padding. I am not sure where the a5 bytes come from!

a5a5a5a5a5a5a5a5a500000000000000000000000000000000000000000000000000000000000000000000000000

Denis Ovsienko

unread,
Jan 21, 2015, 10:43:20 AM1/21/15
to trem...@googlegroups.com
---- On Tue, 20 Jan 2015 19:08:47 +0000 Sadiq Yakasai<sadiq...@gmail.com> wrote ----
> Hello,
>
> I want to create an ethernet frame header and then append raw bytes to the back of this frame. Then generate my packet_out message and send to the OF switch. I am using original Trema (OF 1.0). I am having problems. Can someone help out please. The issue is I am not able to see my received bytes (from socket) - the ethernet header is constructed fine and seen on the wireshark trace.
>

Hello.

I confirm that the Ruby part of Trema generates OFPT_PACKET_OUT messages without a problem and exactly as described in the documentation: http://www.rubydoc.info/github/trema/trema/master/Trema/Controller:send_packet_out

It helps to grep for "send_packet_out" in the source code of Trema and its example applications to see how to use it.

As the application in question is small you could rewrite it in Ruby and see if it fixes the issue. It is does not, then the problem is likely with the application rather than with C part of Trema.

As a side note, if you use a recent version of tcpdump with verbosity level -vvv and higher, it will decode the nested Ethernet frame as well. Maybe that can help.

--
Denis Ovsienko

Sadiq Yakasai

unread,
Jan 21, 2015, 12:52:25 PM1/21/15
to trem...@googlegroups.com
Thanks for your reply Denis!

So I can confirm that the issue is not the generation of packet_out. I have successfully generated several types of packet_out frames (Ethernet + ICMP, IP, UDP, etc) which always work.

What is different this time (with I am having problems with) is that I want to build the Ethernet frame (seen in the code above) but instead of building the next header (which is an EAPOL hearder), I want to get the header byte stream from the socket and just append that at the back of the packet_out (well, actually, at the back of 'frame', which is what packet_out builds from).

Now, I do not know if its my code syntax that is inaccurate or the API does not handle my use case: appending a stream of bytes to a packet_out frame. Hence my query. I have checked a lot of examples in the source code and have not seen a similar use case - all the examples either duplicate a packet_in, or build the ethernet/IP/TCP/UDP headers entirely, to build packet_out (and send out).

Also, I am working with C - the application is much bigger than the snippet I showed and requires C.

Thanks again!
Sadiq

Denis Ovsienko

unread,
Jan 22, 2015, 10:49:58 AM1/22/15
to trem...@googlegroups.com
---- On Tue, 20 Jan 2015 19:08:47 +0000 Sadiq Yakasai<sadiq...@gmail.com> wrote ----
> Hello,
>
> I want to create an ethernet frame header and then append raw bytes to the back of this frame. Then generate my packet_out message and send to the OF switch. I am using original Trema (OF 1.0). I am having problems. Can someone help out please. The issue is I am not able to see my received bytes (from socket) - the ethernet header is constructed fine and seen on the wireshark trace.
>
> See below:
>
> unsigned char *buf;
> buf = (unsigned char *) calloc (1500);

This allocates memory.

>
> int rxBytes = read(sfd, buf, 1500); // read raw bytes from the socket (which is successful)

This reads from the socket into the allocated memory.

>
> buffer *frame = alloc_buffer_with_length( rxBytes + sizeof(ether_header_t) );
> ether_header_t *ether = append_back_buffer( frame, sizeof(ether_header_t) );
>
> buf = (unsigned char *)append_back_buffer( frame, (size_t)rxBytes );

This leaks the allocated memory that holds the data read from the socket and sets the pointer to something else. Probably you want to read from the socket after the line above, not before.

>
> memcpy (ether->macsa, trema_macsa, ETH_ADDRLEN);
> memcpy (ether->macda, pae_group_addr, ETH_ADDRLEN);
> ether->type = htons( ETH_ETHTYPE_8021X );
>
> openflow_actions *actions = create_actions();
> append_action_output( actions, OFPP_FLOOD, UINT16_MAX );
> fill_ether_padding( frame );
>
> buffer *packet_out = create_packet_out( get_transaction_id(), UINT32_MAX, OFPP_NONE, actions, frame);
>
> int ret = send_openflow_message( 1, packet_out);
>

--
Denis Ovsienko

Sadiq Yakasai

unread,
Jan 22, 2015, 5:30:10 PM1/22/15
to trem...@googlegroups.com
You are absolutely right! I have tried your suggestion and it works like a charm!

Although I must say, it vaguely only makes sense. Can you please educate me more this statement:


"This leaks the allocated memory that holds the data read from the socket and sets the pointer to something else. Probably you want to read from the socket after the line above, not before."

Gratitude!

Sadiq

Denis Ovsienko

unread,
Jan 23, 2015, 7:44:47 PM1/23/15
to trem...@googlegroups.com
---- On Thu, 22 Jan 2015 22:30:10 +0000 Sadiq Yakasai wrote ----
>You are absolutely right! I have tried your suggestion and it works like a charm!
>
>Although I must say, it vaguely only makes sense. Can you please educate me more this statement:
>
>"This leaks the allocated memory that holds the data read from the socket and sets the pointer to something else. Probably you want to read from the socket after the line above, not before."

http://en.wikipedia.org/wiki/C_dynamic_memory_allocation

--
Denis Ovsienko

Reply all
Reply to author
Forward
0 new messages