Yes, there is a very big con: libpcap is not what you're looking for.
lipcap by itself has absolutely zero support for building/analyzing TCP, UDP, ICMP (or even IP) packets. It is simply not what it's made for. It can setup filters that match on some TCP/UDP etc, but passed that point you'll have to do all the parsing yourself.
You should have a look at pcap official tutorial:
http://www.tcpdump.org/pcap.html
Go to the section "The actual sniffing". Look at the prototype of the callback libpcap will call when it will capture a packet matching your filter:
void got_packet(u_char *args,
const struct pcap_pkthdr *header,
const u_char *packet);
The packet you'll receive is just a char pointer. You'll have to do all the parsing of it by yourself. As the tutorial goes on:
But how do you make use of this variable (named "packet" in our
prototype)? A packet contains many attributes, so as you can imagine,
it is not really a string, but actually a collection of structures
(for instance, a TCP/IP packet would have an Ethernet header, an IP
header, a TCP header, and lastly, the packet's payload). This u_char
pointer points to the serialized version of these structures. To make
any use of it, we must do some interesting typecasting.
And then you have some code that do just that (with some simplifications so that it's not 10 kilometers long, like "ethernet headers are always exactly 14 bytes" - try that on VLAN!). From then on, for this packet parsing, none of the code is provided by pcap.
Look at pcap API. Do you see anything related to IP/TCP/UDP/ICMP? No.
pcap_activate (3pcap) - activate a capture handle
pcap_breakloop (3pcap) - force a pcap_dispatch() or pcap_loop() call to return
pcap_can_set_rfmon (3pcap) - check whether monitor mode can be set for a not-yet-activated capture handle
pcap_close (3pcap) - close a capture device or savefile
pcap_compile (3pcap) - compile a filter expression
pcap_create (3pcap) - create a live capture handle
pcap_datalink (3pcap) - get the link-layer header type
pcap_datalink_name_to_val (3pcap) - get the link-layer header type value corresponding to a header type name
pcap_datalink_val_to_description (3pcap) - get a name or description for a link-layer header type value
pcap_datalink_val_to_name (3pcap) - get a name or description for a link-layer header type value
pcap_dispatch (3pcap) - process packets from a live capture or savefile
pcap_dump (3pcap) - write a packet to a capture file
pcap_dump_close (3pcap) - close a savefile being written to
pcap_dump_file (3pcap) - get the standard I/O stream for a savefile being written
pcap_dump_flush (3pcap) - flush to a savefile packets dumped
pcap_dump_fopen (3pcap) - open a file to which to write packets
pcap_dump_ftell (3pcap) - get the current file offset for a savefile being written
pcap_dump_open (3pcap) - open a file to which to write packets
pcap_file (3pcap) - get the standard I/O stream for a savefile being read
pcap_fileno (3pcap) - get the file descriptor for a live capture
pcap_findalldevs (3pcap) - get a list of capture devices, and free that list
pcap_fopen_offline (3pcap) - open a saved capture file for reading
pcap_fopen_offline_with_tstamp_precision (3pcap) - open a saved capture file for reading
pcap_free_datalinks (3pcap) - get a list of link-layer header types supported by a capture device, and free that list
pcap_free_tstamp_types (3pcap) - get a list of time stamp types supported by a capture device, and free that list
pcap_freealldevs (3pcap) - get a list of capture devices, and free that list
pcap_freecode (3pcap) - free a BPF program
pcap_get_selectable_fd (3pcap) - get a file descriptor on which a select() can be done for a live capture
pcap_get_tstamp_precision (3pcap) - get the time stamp precision returned in captures
pcap_geterr (3pcap) - get or print libpcap error message text
pcap_getnonblock (3pcap) - set or get the state of non-blocking mode on a capture device
pcap_inject (3pcap) - transmit a packet
pcap_is_swapped (3pcap) - find out whether a savefile has the native byte order
pcap_lib_version (3pcap) - get the version information for libpcap
pcap_list_datalinks (3pcap) - get a list of link-layer header types supported by a capture device, and free that list
pcap_list_tstamp_types (3pcap) - get a list of time stamp types supported by a capture device, and free that list
pcap_lookupdev (3pcap) - find the default device on which to capture
pcap_lookupnet (3pcap) - find the IPv4 network number and netmask for a device
pcap_loop (3pcap) - process packets from a live capture or savefile
pcap_major_version (3pcap) - get the version number of a savefile
pcap_minor_version (3pcap) - get the version number of a savefile
pcap_next (3pcap) - read the next packet from a pcap_t
pcap_next_ex (3pcap) - read the next packet from a pcap_t
pcap_offline_filter (3pcap) - check whether a filter matches a packet
pcap_open_dead (3pcap) - open a fake pcap_t for compiling filters or opening a capture for output
pcap_open_dead_with_tstamp_precision (3pcap) - open a fake pcap_t for compiling filters or opening a capture for output
pcap_open_live (3pcap) - open a device for capturing
pcap_open_offline (3pcap) - open a saved capture file for reading
pcap_open_offline_with_tstamp_precision (3pcap) - open a saved capture file for reading
pcap_perror (3pcap) - get or print libpcap error message text
pcap_sendpacket (3pcap) - transmit a packet
pcap_set_buffer_size (3pcap) - set the buffer size for a not-yet-activated capture handle
pcap_set_datalink (3pcap) - set the link-layer header type to be used by a capture device
pcap_set_immediate_mode (3pcap) - set immediate mode for a not-yet-activated capture handle
pcap_set_promisc (3pcap) - set promiscuous mode for a not-yet-activated capture handle
pcap_set_rfmon (3pcap) - set monitor mode for a not-yet-activated capture handle
pcap_set_snaplen (3pcap) - set the snapshot length for a not-yet-activated capture handle
pcap_set_timeout (3pcap) - set the read timeout for a not-yet-activated capture handle
pcap_set_tstamp_precision (3pcap) - set the time stamp precision returned in captures
pcap_set_tstamp_type (3pcap) - set the time stamp type to be used by a capture device
pcap_setdirection (3pcap) - set the direction for which packets will be captured
pcap_setfilter (3pcap) - set the filter
pcap_setnonblock (3pcap) - set or get the state of non-blocking mode on a capture device
pcap_snapshot (3pcap) - get the snapshot length
pcap_stats (3pcap) - get capture statistics
pcap_statustostr (3pcap) - convert a PCAP_ERROR_ or PCAP_WARNING_ value to a string
pcap_strerror (3pcap) - convert an errno value to a string
pcap_tstamp_type_name_to_val (3pcap) - get the time stamp type value corresponding to a time stamp type name
pcap_tstamp_type_val_to_description (3pcap) - get a name or description for a time stamp type value
pcap_tstamp_type_val_to_name (3pcap) - get a name or description for a time stamp type value
(And BTW there is nothing either to build packets, just to send some)
Now, regarding the idea of raw sockets:
If you want to send and receive TCP and UDP, why not go for TCP and UDP sockets directly?
Finally, look here and google around for networking libraries that will best suits your needs:
Best C/C++ Network Library