All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.pkts.examples.core.CoreExample002 Maven / Gradle / Ivy

There is a newer version: 3.0.10
Show newest version
package io.pkts.examples.core;

import io.pkts.PacketHandler;
import io.pkts.Pcap;
import io.pkts.PcapOutputStream;
import io.pkts.packet.Packet;
import io.pkts.packet.UDPPacket;
import io.pkts.packet.sip.SipPacket;
import io.pkts.protocol.Protocol;
import io.pkts.sdp.RTPInfo;
import io.pkts.sdp.SDP;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * This is an example that takes a pcap and extracts outs a particular SIP call along
 * with the potential RTP and writes it to a new pcap.
 *
 * This is very useful if you run a full tcpdump on your production machines and then
 * would like to extract out individual calls. This is also possible to do with wireshark
 * but it has a tendency to crash for larger files. Plus, who wants to do it manually anyway...
 *
 * @author [email protected]
 */
public class CoreExample002 {

    public static void main(final String[] args) throws IOException {

        // Step 1 - accept two inputs, first one being the pcap from which we will read
        //          and the second argument being the SIP Call-ID we are looking for.
        final File inputFile = new File(args[0]);
        final String callId = args[1];

        // Step 2 - obtain a new Pcap instance by supplying an InputStream that points
        //          to a source that contains your captured traffic. Typically you may
        //          have stored that traffic in a file so there are a few convenience
        //          methods for those cases, such as just supplying the name of the
        //          file as shown below.
        final Pcap pcap = Pcap.openStream(inputFile);

        // Step 3 - Create a new Pcap output stream, to which we will be writing all
        //          those packets we wish to save.
        final File outputFile = new File(inputFile.getParentFile(), callId + ".pcap");
        final PcapOutputStream out = pcap.createOutputStream(new FileOutputStream(outputFile));

        // Step 4 - Since we also want to save any potential RTP for this call
        //          we need to process the SDP in the SIP traffic and check
        //          which ip:port RTP will be coming from for this particular call.
        //          Later on, we will use this information to check if a particular UDP
        //          packet is to/from this IP:port and if so, we will save that packet.
        final List rtpInfo = new ArrayList<>();

        // Step 5 - Once you have obtained an instance, you want to start
        //          looping over the content of the pcap. Do this by calling
        //          the loop function and supply a PacketHandler, which is a
        //          simple interface with only a single method - nextPacket
        pcap.loop(new PacketHandler() {
            @Override
            public boolean nextPacket(final Packet packet) throws IOException {

                // Step 6 - In this example we assume SIP & RTP is both over UDP. For
                //          RTP that will most likely always be true (even though you
                //          can technically push it over TCP as well) but certainly not
                //          always true for SIP. However, this is just an example so we
                //          will keep this shortcut for illustrative purposes :-)
                if (packet.hasProtocol(Protocol.UDP)) {
                    final UDPPacket udp = (UDPPacket) packet.getPacket(Protocol.UDP);

                    // Step 7 - If the packet is SIP and matches the call-id we are looking
                    //          for then just save it to the output stream.
                    if (packet.hasProtocol(Protocol.SIP)) {
                        final SipPacket sip = (SipPacket) packet.getPacket(Protocol.SIP);
                        if (callId.equals(sip.getCallIDHeader().getValue().toString())) {
                            out.write(sip);

                            // Step 8 - if the message also has content (and we blindly assume it
                            //          is SDP, which we obviously should check) then extract out
                            //          the RTP information and save that so we later can check if
                            //          a packet is to/from this IP:port
                            if (sip.hasContent()) {
                                final SDP sdp = (SDP) sip.getContent();
                                sdp.getRTPInfo().forEach(info -> rtpInfo.add(info));
                            }

                        }
                    } else if (rtpInfo.stream().filter(info -> (info.getAddress().equals(udp.getDestinationIP()) && info.getMediaPort() == udp.getDestinationPort())
                                    || (info.getAddress().equals(udp.getSourceIP()) && info.getMediaPort() == udp.getSourcePort())
                    ).findFirst().isPresent()) {
                        // Step 9 - If the incoming UDP packet is from any known address
                        //          as listed in an SDP then just save it.
                        out.write(packet);
                    }
                }

                return true;
            }
        });

        out.flush();
        out.close();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy