By default, tun devices operate in the layer 3 mode, aka point to point. You're asking for layer 2 mode which more closely resembles a generic Ethernet device. Linux calls these tap devices. In OpenBSD you can switch a tun device into layer 2 mode with "ifconfig tun0 link0". The Macintosh tuntaposx driver mimics Linux' device schism; open a tap device instead.
You might want to review https://community.openvpn.net/openvpn/wiki/BridgingAndRouting to determine if you really want tap devices. They add a little overhead. If you just need two boxes to pass IP packets between each other and no bridging or broadcasting to a larger subnet, point to point should be sufficient.
For example, if you have two machines, one we label "local" with a LAN IP address like 192.168.0.12 and another we label "remote" with a LAN IP address like 192.168.1.14, you can assign tunnel IP addresses thusly:
ifconfig tun0 inet 10.0.0.1 10.0.0.2 up
on the local system, and:
ifconfig tun0 inet 10.0.0.2 10.0.0.1 up
on the remote system. Note the reversed perspective on the remote machine. Do not set your point to point addresses to anything on an existing subnet; it will not route properly.
I can't stress this enough: read and re-read the manual pages ("man ifconfig" and "man tun", probably others) until they make sense. My ifconfig examples above may differ slightly from your operating system.
And for another perspective you might look into GRE tunnels as their functionality mirrors what you describe for your program. However, GRE is likely not viable in today's TCP-centric networks nor is it a good idea due to major security issues.
If your goal is to circumvent an overbearing firewall, be aware that many such firewalls block UDP (and especially GRE) packets. In such a case, try SSH interface tunneling to set up tun/tap interfaces and forward packets. You get encryption and optionally compression as well. :)