NETSED(1)

πŸ’– NETSED β€” the manual, but make it slay πŸ’–

okay bestie, gather round, because this one is genuinely iconic. we're talking about netsed, aka the NetSED network stream editor, and yes she is exactly what she sounds like. πŸ¦‹


✨ NAME ✨

netsed β€” a network stream editor. that's it, that's the whole name. short, sweet, main character energy. πŸ‘‘


✨ SYNOPSIS ✨

netsed {proto} {lport} {rhost} {rport} {rule} [rule ...]

like, that's the summoning circle. five things minimum, then as many extra rules as your heart desires. πŸ’…


✨ DESCRIPTION ✨

so netsed is this little utility β€” small, handy, lowkey a menace β€” that alters the contents of packets in real time as they get forwarded through a network stream, or in a datagram connection. it just sits there in the middle, vibing, and rewrites stuff as it flies past. ✨

when you call it with a set of replacement rules, every single one of those rules gets tested for applicability against each packet entering in either direction. every packet. both ways. no skipping. periodt.


✨ ARGUMENTS ✨

  • proto β€” this one decides the protocol for the connection you want. your options are "tcp", "TCP", "udp", or "UDP". yes, she takes the shouty versions too, she's not picky. πŸŽ€
  • lport β€” the local listening port for the connection. you can hand her a service name or a numerical port value, whichever you vibe with. πŸ’œ
  • rhost β€” the remote host you wanna connect to. resolvable host names and IPv4/IPv6 addresses are all equally usable here, no discrimination. 🌈

now, special case alert 🚨: if you assign "0" to rhost, netsed inserts the kernel's knowledge of the targeted host address. this is for when a netfilter rule is redirecting traffic β€” which is exactly what happens when you're running a transparent proxy service. iykyk. 🫢

  • rport β€” the remote port to connect to. again, service name or numerical port value, both fine. 🌸

and here too, a value of "0" is acceptable, to arrange a transparent proxy service β€” the kernel's tracking will provide the intended remote port number for you. so thoughtful of her honestly. 😭

  • rule β€” at least one replacement rule is mandatory. mandatory mandatory. you cannot skip this one bestie. the general syntax goes like this:
s/pat1/pat2[/flag]

the effect? it replaces the text that matches pat1 with the expansion of pat2. that's the whole thing. πŸ’…

the optional parameter flag is a composite β€” it contains either a numerical value that limits the maximal number of times the rule can be applied, or a direction semaphore telling you the rule only applies to incoming traffic (coded as 'I' or 'i') or outgoing traffic (coded as 'O' or 'o'). you could say the rule expires after num occurrences. cute little self-destruct timer, honestly. πŸ’€

the rules get applied in succession to all passing packets, flowing in either direction. and the moment a rule has expired, it's removed from the collection of active rules for the current connection. gone. bye. πŸ‘‹

⭐ important detail: any counter is started when the connection is initiated, and it runs as long as the connection is alive.

this holds directly for TCP connections. for UDP though, a connection is considered to consist of incoming data on a fixed address and a fixed port, together with any response from a remote server. and when no datagrams have been transmitted for a period of 30 seconds, the UDP connection is seen as closed. so if it goes quiet for 30 seconds, she assumes the situationship is over. πŸ™ˆ

also! a single rule is limited to acting on individual packets. a pattern cannot match across packet boundaries. she does not do cross-packet reach-arounds, sorry. 🚫

and here's the fun part: using HTTP-like escape sequences for hexadecimal values, all eight-bit characters are viable in your patterns. so the standard character pair CRNL would code as "%0a%0d". 🌟

but listen β€” in a pattern, the percentage sign itself must be escaped by duplication. so a string "%%" gets interpreted in a pattern as a literal percentage sign. don't forget it, or your pattern will do something cursed. πŸ’€


✨ EXAMPLES ✨

a handful of replacement rules, because examples are the bestie that makes everything make sense. 🫢

  • s/andrew/mike β€” replace every occurrence of the string "andrew" with "mike", in every passing packet. all of them. no mercy. πŸ”₯
  • s/andrew/mike/1 β€” replace only the first occurrence of the string "andrew" with "mike" in each packet. any repetition stays unaltered, unless a further rule specifies some replacement. one and done. ✨
  • s/andrew/mike%00%00 β€” replace in each packet every occurrence of the string "andrew" with "mike\x00\x00". the padding with two null bytes keeps the packet length unaltered, which might be essential at times. like, genuinely essential. πŸŽ€
  • s/%%/%2f/20 β€” replace the first twenty occurrences of the percentage character '%' with slashes '/'. twenty. exactly twenty. πŸ‘‘
  • s/Rilke/Proust/o, s/Proust/Rilke/i β€” let Rilke travel incognito as Proust πŸ•΅οΈ β€” on outgoing packets, replace Rilke's real sirname by Proust, then restore it again in any incoming packet. a whole disguise arc, back and forth, in two rules. iconic behaviour. 🌈

✨ AUTHOR ✨

this text was initially compiled by Mats Erik Andersson as a Docbook source from the usage printout. πŸ’œ

permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, version 2, or of a later version. so go forth and remix, bestie. 🫢


Copyright Β© 2010-2014 Mats Erik Andersson


and that's the whole page! 🌸 this was NetSED 1.2, dated May 23rd, 2014 β€” yeah she's an elder but she still ate, no cap. go forth, edit your streams, and remember: escape your percentage signs. πŸ’…βœ¨