Question

I'm trying to spec out the foundations for a server application who's purpose will be to..

1 'receive' tcp and/or udp packets
2 interpret the contents (i.e. header values)

To add more detail, this server will receive 'sip invites' and respond with a '302 redirect'.

I have experience with Net::Pcap and perl, and know I could achieve this by looping for filtered packets, decoding and then using something like Net::SIP to respond.

However, there's a lot of bloat in both of these modules/applications I don't need. The server will be under heavy load, and if I run TCPDUMP on it's own, it loses packets in the kernel due to server load, so worry it wont be appropriate :(

Should I be able to achieve the same thing by 'listening' on a socket (using IO::Socket for example) and decoding a packet?

Unfortunatly by debugging, it's hard to tell if IO::Socket will give me the opportunity to see a raw packet? And instead it automatically decodes the message to a readable format!

tl;dr: I want to capture lots of SIP Invites, analyse the head values, and respond with a SIP 302 redirect. Is there a better way than using tcpdump (via Net::Pcap) to achieve this?

Thanks, Moose

Was it helpful?

Solution

Is there a better way than using tcpdump (via Net::Pcap) to achieve this?

Yes. Using libpcap (that's what you meant instead of tcpdump in that question) is a bad way to implement a TCP-based service, as you will have to reimplement much of TCP yourself (libpcap gives you raw network-layer packets), and the packets your program gets will also get delivered to the Internet protocol stack on your machine, so:

  • if there's nothing on your machine listening on the TCP port to which the other machines are trying to connect, the connection requests will get a RST from the TCP code and think the connection attempt failed;
  • if there is something on your machine listening on that port, it'll probably accept the connection, and it and your program will both try to communicate with the other machine, which will probably confuse its TCP stack and cause various bad and random things to happen.

It's not much better for UDP:

  • if there's nothing on your machine listening on the UDP port to which the other machines are trying to connect, the connection requests will probably get an ICMP Port Unreachable message from the UDP code, which may make it think the connection attempt failed;
  • if there is something on your machine listening on that port, it'll probably accept the connection, and it and your program will both try to communicate with the other machine, which will probably confuse its SIP stack and cause various bad and random things to happen.

IO:Socket will probably not give you raw packets, and that's a good thing; you won't have to implement your own IP and TCP/UDP stack. If your goal is to implement a redirect server on your machine, you have no need to receive raw packets; you want to receive SIP INVITEs with all the lower-level processing done for you by your machine's IP/TCP/UDP stack.

If you already have a SIP implementation on your machine, and you want to act as a "firewall" for it, so that, for some INVITEs, you send back a 302 redirect and prevent the SIP implementation on your machine from ever seeing the INVITEs in question, you will need to use the same mechanism that your particular OS uses to implement firewalls. There is no libpcap-like wrapper for those mechanisms, as far as I know.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top