The definition of a symmetric NAT is one where mappings depend entirely on the combination of [src ip, src port, dest ip, dest port, and probably IP version and / or transport protocol].
NOW: that is not to say that it isn't still possible to bypass symmetric NATs though. You have a number of possibilities here:
- The NAT allocates random ports = you're screwed. There are like 68k valid ports. Both sides need to guess the others mapping. The chances of that occurring are (1 / 68000) * (1 / 68000) = infinitesimal. It's just not gonna happen.
- The NATs use a predictable distance of N between mappings irrespective of [src ip, src port...]. N may be positive or negative modulo MAX_PORT.
- The NAT preserves the distance between local ports + or - the distance between remote ports. So if local (1000) = remote (553); local (2000) == remote(1553).
- The NAT does the same as above but ONLY if the local port increases by 1. The other scenario is if it increases by 2 (some routers do this so it's good to test for it.)
- Some researchers have found routers that allocate mappings going up and down based on some function. Others have found routers that 'skip alternative ports' (not too sure what this means as it's too vague.)
- I've saved the best for last: many routers simply preserve the source port. E.g. local (N) = remote (N).
Every single one of these options save for (1) means you can bypass symmetric NATs and hence is worth writing code for. You cannot brute force the connections between two random symmetric NATs. The exception is if you rooted both routers and wrote your own iptable routes to make ports predictable. But lets face it: its not practical to do such a thing.
I am still researching port mapping behaviours myself, but this answer should indicate how the vast majority of NATs behave in the real world. In addition to their mapping characteristics, you ought to be aware of the types of NATs because they dictate restrictions on how the mappings can be used. Like port restricted NATs = huge pain in the ass.