Here is my answer to my knowledge:
1) Yes. You are correct in declaring int sock_raw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
2) Your device needs to be in Monitor Mode to capture beacon frames. If your linux machine has the aircrack-ng
suite installed, you can use airmon-ng start [DEV NAME]
to put it into monitor mode or if net-tools are installed etc, you can do the following (example uses 'wlan0' as device i want to put into monitor mode):
ifconfig wlan0 down
iw wlan0 set type monitor
ip link set wlan0 name wlan0mon && ifconfig wlan0mon up
Next, if you want to continue using your monitor mode socket in C, you can use the following:
struct ifreq ifr;
struct sockaddr_ll ll;
assert(sizeof(ifr.ifr_name) == IFNAMSIZ);
int sock_raw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
strncpy(ifr.ifr_name, "wlan0mon", sizeof(ifr._ifr_name));
ioctl(sock_raw, SIOCGIFINDEX, &ifr);
ll.sll_ifindex = ifr.ifr_ifindex;
ll.sll_protocol = htons(ETH_P_ALL);
ll.sll_family = PF_PACKET;
bind(sock_raw, (struct sockaddr *)&ll, sizeof(ll));
This C code sets the raw socket up for monitor mode use then binds it to the monitor mode device. Now it is able to be used to send/recv 802.11 frames etc. I hope this helps :)