Search code examples
c++linuxsocketsethernet

Can I write Ethernet based network programs in C++?


I would like to write a program and run it on two machines, and send some data from one machine to another in an Ethernet frame.

Typically application data is at layer 7 of the OSI model, is there anything like a kernel restriction or API restriction, that would stop me from writing a program in which I can specify a destination MAC address and have some data sent to that MAC as the Ethernet payload? Then write a program to listen for incoming frames and grab the frames from a specified source MAC address, extracting the payload of data from the frame?

(So I don't want any other overhead like IP or TCP/UDP headers, I don't want to go higher than layer 2).

Can this be done in C++, or must all communication happen at the IP layer, and can this be done on Ubuntu? Extra love for pointing or providing examples! :D

My problem is obviously I'm new to network programming in c++ and as far as I know, if I want to communicate across a network I have to use a socket() call or similar, which works at an IP layer, so can I write a c++ program to work at OSI layer 2, are there APIs for this, does the Linux kernel even allow this?


Solution

  • As you already mentioned sockets, probably you would just like to use a raw socket. Maybe this page with C example code is of some help.


    In case you are looking for an idea for a program only using Ethernet while still being useful:

    Wake on LAN in it's original form is quite simple. Note however that most current implementations actually send UDP packets (exploiting that the receiver does not parse for packet headers etc. but just a string in the packet's payload).


    Also the use of raw sockets is usually restricted to privileged users. You might need to either

    • call your program as root
    • or have it owned by root and setuid bit set
    • or set the capability for creating raw socket using setcap CAP_NET_RAW+ep /path/to/your/program-file

    The last option gives more fine grained privileges (just raw sockets, not write access to your whole file system etc.) than the other two. It is still less widely known however, since it is "only" supported from kernel 2.6.24 on (which came with Ubuntu 8.04).