The TCP/IP subsystem in Illumos does support "raw" sockets. And by "raw", I mean, "raw that's not the base IP header." This enabled ping(1M) to work. It also allows a privileged user program to send raw TCP segments. The problem is, the Illumos TCP/IP subsystem does not deliver packets to raw sockets that aren't specifically ICMP or "raw SCTP" (presumably the latter is for a 3rd-party SCTP stack). If one attempts to send a raw SYN using the attached test program (tcp-3rd-data.c), the traffic looks like: we -> target SYN target -> we SYN/ACK we -> target RST because the TCP/IP subsystem attempts to find an active connection for the inbound SYN/ACK. To avoid this, let's bring to bear the IPsec Security Policy Database (SPD): specifically, its DROP action. We can dropping packets with our selected local port and fed that into ipsecconf(1M): { lport 5555 dir both } drop {} This will now prevent the inbound SYN/ACK from going anywhere that will generate a RST. The problem now is, our test program has no way of seeing what the peer's sequence number is. We must snoop the packets. Luckily, snoop's default output helps here. For example: target -> we TCP D=5555 S=22 Ack=12345679 Seq=3906334614 Len=0 Win=65392 The "Seq" value (plus one) can be used to transmit an appropriate ACK with the test program. For best results, the test program's second invocation should also increase the sequence number to reflect the additional data we're sending. For example: (0)# ./a.out 10.1.1.6 10.1.1.137 5555 22 12345678 0 tcp cksum == 0x268e (0)# ./a.out 10.1.1.6 10.1.1.137 5555 22 12345691 304354784 tcp cksum == 0xe3a7 Cheesy, but effective. It panics a non-1775-fixed kernel, works pre-1631, and post-1775. Unless you're using IPsec for other reasons, don't forget to flush the SPD afterwards: ipsecconf -f