1

How to create Ethernet II frame header in Linux ? 802.3 frame header can be created using eth_header() giving the skbuffer and source and destination MAC and length. Can the same function be used for Ethernet II frame format also, where we use type field instead of length?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
user1023527
  • 41
  • 2
  • 7

2 Answers2

1

The (current) kernel sources define the method in question the following way:

int eth_header(struct sk_buff *skb, struct net_device *dev,
           unsigned short type,
           const void *daddr, const void *saddr, unsigned len);

So we do have a type field. So far so good.

Let's look at the method's implementation, whether and how the value of type is taken into account. The method starts like this:

{
    struct ethhdr *eth = ...

    if (type != ETH_P_802_3 && type != ETH_P_802_2)
            eth->h_proto = htons(type);
    else
            eth->h_proto = htons(len);
    ...

As we can see, for all types but 802.2/3 the value of type (passed to the function) is used to initialise the frame header, which is what we want for Ethernet II frame headers.

Conclusion and answer to the question: Yes, one can use eth_header() to create an Ethernet II frame header.

alk
  • 69,737
  • 10
  • 105
  • 255
  • Thanks for the reply. Let us say for example i have a type field of 8100(vlan tagging) so when i call this function i should pass ETH_P_802_2 to type filed and 8100 to len field .Is that correct? – user1023527 Jan 02 '12 at 06:28
  • @user1023527: Actullay this could work (at leasth using the currrent sources) ... - but I'd recommend to pass `ETH_P_8021Q` (from `/usr/src/linux/include/linux/if_ether.h`) via `type` and pass nothing (`0`) via `len`. – alk Jan 02 '12 at 07:54
  • @user1023527: *"VLAN tagging*" is 802.1Q (`ETH_P_8021Q`) and `ETH_P_8021Q` in turn is `#define`ed to be `8100`. – alk Jan 04 '12 at 07:54
0

Cf. net/ipv6/netfilter/ip6t_REJECT.c and net/ethernet/eth.c.:

nskb = skb_alloc(...);
...
struct ethhdr *eh = skb_push(nskb, sizeof(struct ethhdr));
eh->h_proto = htons(ETH_P_IPV6);

You can change the amount of bytes allocated and/or pushed depending on what you want to add to the packet.

jørgensen
  • 10,149
  • 2
  • 20
  • 27