If you are happy with packet contents after decryption, you can use a rooted Android phone with a Qualcomm baseband. I have did implement this for SRLab's SnoopSnitch.
The low-level code can get you started: it opens the Qualcomm debug monitor device /dev/diag
and streams messages coming in over this interface. You will then have to send configuration messages to enable logging for the packet type classes you are interested in. This part of the code will point you in the right way. You may have to dig through the rest of the repository to see how the data can be used.
The Qualcomm QXDM tool can show raw messages and decode them - this will help in reverse engineering the data format used in the messages.