I had a similar requirement. To receive packets with a specific VLAN, I created a VLAN interface and bound my raw socket to it. Now I can just send 802.3 frames, the kernel inserts/extracts VLAN tag.
Create a VLAN interface, you should have root permission
ip link add link <phyInterface> name <phyInterface.VLANID> type vlan id VLANID
Eg: ip link add link eth0 name eth0.100 type vlan 100
Use normal bind function in your application to bind to the VLAN interface. In the above example eth0.100.
You can refer to the below two links for sample code (I am NOT the owner of the code)
Sending: https://gist.github.com/austinmarton/1922600
Receiving: https://gist.github.com/austinmarton/2862515#file-recvraweth-c
The only change needed is that instead of binding to physical interface, bind to the virtual VLAN interface. Note that the Ethernet frames received are un-tagged frames. Any frames sent on this interface will automatically tagged with the VLANID.