How to write packets from vpn tunnel to pcap file - java

I used the Android's ToyVpnClient to set up a tunnel and intercept incoming & outgoing packets. I want to write these packets from this tunnel, which is stored in a ByteBuffer, to a pcap file. I've looked at jpcap and jnetpcap, but they seem to only support creating the pcap file from the packets that were captured by using these libraries to listen to the device's network interfaces in the first place.
Is there any api available that would help me create the pcap file from the tunnel's packet data stored in the ByteBuffer? If I were to create my own pcap writer, how would i go about parsing this packet from the tunnel and put it into the pcap format? (I've looked but haven't found any examples)
Here's the relevant code sample from the ToyVpnClient:
...
DatagramChannel tunnel = DatagramChannel.open();
// Connect to the server.
tunnel.connect(server);
// Packets to be sent are queued in this input stream.
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
// Packets received need to be written to this output stream.
FileOutputStream out = new FileOutputStream(mInterface.getFileDescriptor());
// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);
// keep forwarding packets till something goes wrong.
while (true) {
// Read the outgoing packet from the input stream.
int length = in.read(packet.array());
if (length > 0) {
// Write the outgoing packet to the tunnel.
packet.limit(length);
tunnel.write(packet);
//How to write to pcap file here?
packet.clear();
}
...
}
Thank you

For anyone looking for similar solution, I got it working using the netutils library's PCapFileWriter and modifying it to include a fake ethernet header for each packet (http://code.google.com/p/netutils/)

Related

Sending Protocol Buffer encoded message from Python Server to Java Client

I'm writing a little server that uses protocol buffer to encode some data.
TCP Socket is opened between Android Client and Python Server
Android Client sends string for processing as normal newline delimited utf-8.
Python Server does some processing to generate a response, which gives an Array of Int Arrays: [[int]]. This is encoded in the protocol buffer file:
syntax = "proto2";
package tts;
message SentenceContainer {
repeated Sentence sentence = 1;
}
message Sentence {
repeated uint32 phonemeSymbol = 1;
}
It gets loaded into this structure and sent as follows...
container = ttsSentences_pb2.SentenceContainer()
for sentence in input_sentences:
phonemes = container.sentence.add()
# Add all the phonemes to the phoneme list
phonemes.phonemeSymbol.extend(processor.text_to_sequence(sentence))
payload = container.SerializeToString()
client.send(payload)
Android Client receives Protocol Buffer encoded message and tries to decode.
This is where I'm stuck...
# I get the InputStream when the TCP connection is first opened
bufferIn = socket.getInputStream();
TtsSentences.SentenceContainer sentences = TtsSentences.SentenceContainer.parseDelimitedFrom(bufferIn);
When receiving the message the client gets this exception:
E/TCP: Server Error
com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag.
at com.google.protobuf.CodedInputStream.checkLastTagWas(CodedInputStream.java:164)
at com.google.protobuf.GeneratedMessageLite.parsePartialDelimitedFrom(GeneratedMessageLite.java:1527)
at com.google.protobuf.GeneratedMessageLite.parseDelimitedFrom(GeneratedMessageLite.java:1496)
at com.tensorspeech.tensorflowtts.TtsSentences$SentenceContainer.parseDelimitedFrom(TtsSentences.java:221)
at com.tensorspeech.tensorflowtts.network.PersistentTcpClient.run(PersistentTcpClient.java:100)
at com.tensorspeech.tensorflowtts.MainActivity.lambda$onCreate$0$MainActivity(MainActivity.java:71)
at com.tensorspeech.tensorflowtts.-$$Lambda$MainActivity$NTUE8bAusaoF3UGkWb7-Jt806BY.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:919)
I already know this problem is caused because Protocol buffer is not self delimiting, but I'm not sure how I'm supposed to properly delimit it. I've tried adding a newline client.send(payload + b'\n'), and adding in the PB size in bytes to the beginning of the payload client.send(container.ByteSize().to_bytes(2, 'little') + payload), but am not sure how to proceed.
It's a shame there's no documentation on how to use Protocol Buffer over TCP Sockets in Java...
OK, I worked this out...
In the case where you have a short-lived connection, the socket closing would signify the end of the payload, so no extra logic is required.
In my case, I have a long-lived connection, so closing the socket to signify the end of the payload wouldn't work.
With a Java Client & Server, you could get around this by using:
MessageLite.writeDelimitedTo(OutputStream)
then on the recipient side:
MessageLite.parseDelimitedFrom(InputStream).
Easy enough...
But in the Python API, there is no writeDelimitedTo() function. So instead we must recreate what writeDelimitedTo() is doing. Fortunately, it's simple. It simply adds a _VarintBytes equal to the payload size to the beginning of the message!
client, _ = socket.accept()
payload = your_PB_item.SerializeToString()
size = payload.ByteSize()
client.send(_VarintBytes(size) + payload)
Then on the Java recipient side...
bufferIn = socket.getInputStream();
yourPbItem message;
if ((message = yourPbItem.parseDelimitedFrom(bufferIn)) != null) {
// Do stuff :)
}
This way, your protocol buffer library knows exactly how many bytes to read, and then to stop caring about the InputStream, rather than sitting listening indefinitely.

Read JPEG bytes from TCP socket (Android)

I have an application that show CCTV feed from mobile. I successfully develop iOS application and now my client wants me to port to Android. The porting was fine until I'm stuck at this part of code.
This part of code, I have to connect to TCP socket server. When connected, I don't have to send server any thing, instead, server will send me a JPEG image. So, after connected, I'll have to keep reading until I received JPEG end marker (0xFF, 0xD9) and then close the connection.
What I plan to do is
Socket s = new Socket("Server IP Addreess", SERVER_PORT);
DataInputStream dis = new DataInputStream(socket.getInputStream());
ArrayList<Byte> bytes = new ArrayList<Byte>();
boolean err = false;
while (true) {
byte b = dis.readByte();
if (b == -1) {
err = true;
break;
}
bytes.add(b);
if ((bytes.get(bytes.size() - 1) == (byte) 0xFF) &&
(bytes.get(bytes.size() - 2) == (byte) 0xD9)) {
break;
}
}
socket.close();
if (!err) {
// create bitmap from byte array and show in ImageView
}
But I'm not sure that this is correct or not. The other solution I'm thinking about is
Socket s = new Socket("Server IP Addreess", SERVER_PORT);
BitmapFactory.decodeStream(s.getInputSteam());
But, also, I don't know how to close socket when server send 0xFF, 0xD9. Or will the BitmapFactory will detect that marker and close socket connection for me?
Any suggestion are welcome. Thank you!
P.S. I don't have test environment as they took it back when I delivered iOS app. So, I have to develop and then deliver to them to test (by playing with the app). Then if it's not working, they will tell me to correct it but I won't be able to access LogCat or other useful information. This is just like trying to sew a button in dark room, and I can't turn on the light.
: |
EDIT
More information about this server
Server won't send length of file, so, number of bytes for each file is unknown.
I have to detect 0xFF, 0xD9 that indicate end of file.
Problem is, I have to terminate socket connection from my side, server won't do it.
I can't change the way server works, it's hardware that my client purchase.
Also, I'm getting one image for each TCP connection, I'm not getting multiple images for single TCP connection.
This is a bad idea to just look for some magic bytes to determine the end of the data. While these magic bytes should be at the end of the file they can also happen inside the data.
Better would be to either prefix the data with the length or use a separate TCP connection for each jpeg file and just read until the end of connection (that is until you don't get any more data). If this is not possible you have to do more advanced parsing, see Detect Eof for JPG images.

How to read the data from datastream

Please help me out on how to read the stream of data in java. My requirement is to make the telnet connection to the router. This part is accomplished. From the router, Have to connect to the xxx remote machine using its ip address and port number through telnet. While making this connection, i am getting some response. But while reading, the program control stops at read() method of InputStream class. Here are the code snippet which i am using to read the stream of data.
buff = new byte[4*1024];
ret_read = 0;
do
{
ret_read = in.read(buff); // Program control gets hanged here. Once all the data are read...
if(ret_read > 0)
{
System.out.println(new String(buff,0,ret_read));
}
}while(ret_read > 0);
What is happening is the read is blocking and waiting for more data to be sent on the stream, it will continue to do that until the stream is closed or more data is sent.
You need to either use a non-blocking read, put a timeout on the read, or close the stream server side after it finishes sending the data.

UDP port scanning Java finds only 1 open UDP port

I have an assigment about port scanning. I am scanning UDP ports of some IP addresses in Java.In my program (assuming everything is OK) I can only find one open UDP port. In the other hands port scanning over "nmap" I get 4 open UDP ports. Can somebody tell me why I can not find more than one ports via Java code?
By the way I can find the true open port in my code.
int startPortRange=1;
int stopPortRange=1024;
InetAddress address = InetAddress.getByName("bigblackbox.cs.binghamton.edu");
int counter=0;
for(int i=startPortRange; i <=stopPortRange; i++)
{
counter++;
try{
byte [] bytes = new byte[128];
DatagramSocket ds = new DatagramSocket();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.setSoTimeout(100);
ds.connect(address, i);
ds.send(dp);
ds.isConnected();
dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
ds.close();
System.out.println("open");
System.out.println(counter);
}
catch(InterruptedIOException e){
//System.out.println("closed");
}
catch(IOException e){
//System.out.println("closed");
}
}
Output of above code is
135 open
When I make same operation in command line using nmap I get more open ports.
I could not upload an image because I am a new user.
Thank you
It is impossible to provide a concrete answer, unless you provide at least:
The source code of your program.
An example of the (incorrect) output that you are getting.
The expected output for the same scenario.
Without this information there is no way for us to tell you what is wrong. For all we know, it could even be a simple case of your program terminating prematurely after finding an open port. Or a case of the open port that was last found overwriting the entries of the previous ones before being displayed.
In any case, it might be worthwhile to investigate what is being sent and received using a network sniffer, such as Wireshark. By comparing an nmap session with a session created by your program, you might be able to spot some significant difference that would help pinpoint the issue.
EDIT:
After having a look at your code and comparing with nmap, it seems that you are mistakenly handling the case of a SocketTimeoutException as a closed port, while it could simply be the port of a server that refuses to answer to the packet that you sent.
EDIT 2:
Here's the full story:
When a port is properly closed, the server sends back an ICMP Destination Unreachable packet with the Port unreachable error code. Java interprets this error to an IOException that you correctly consider to indicate a closed port.
An open port, on the other hand may result into two different responses from the server:
The server sends back a UDP packet, which is received by your program and definitely indicates an open port. DNS servers, for example, often respond with a Format error response. nmap shows these ports are open.
The server ignores your probe packet because it is malformed w.r.t. to the provided service. This results in a network timeout and a SocketTimeoutException in your program.
Unfortunately there is no way to tell whether a network timeout is because an active server ignored a malformed probe packet or because a packet filter cut down the probe. This is why nmap displays ports that time out as open|filtered.

how to filter rtsp packets from a pcap file

i'm writing a program to open a pcap file and then filter some packets and then write packet data as string in a file but i do nott know why this progrme is doing nothing after opening the pcap file.
int rtsp=0;
FileWriter fstream2= new FileWriter("E:\write2.txt",true);
BufferedWriter fbw2= new BufferedWriter(fstream2);
System.out.println("RTSP:");
JpcapCaptor captor2=JpcapCaptor.openFile("E:\rtsp_with_data_over_tcp.pcap");
while(true){
Packet packet2=captor2.getPacket();
if(packet2==null || packet2==Packet.EOF) break;
rtsp=rtsp+1;
String PacketData2=new String(packet2.data);
fbw2.write(PacketData2);
fbw2.newLine();
}
fbw2.close();
captor2.close();
System.out.println("RTSP:"+rtsp);
EVEN this last print statement is also not working.
can any one guide me? !
According to the default ports used by rtsp, you can filter the
rtsp 554/tcp Real Time Stream Control Protocol
rtsp 554/udp Real Time Stream Control Protocol
rtsp-alt 8554/tcp RTSP Alternate (see port 554)
rtsp-alt 8554/udp RTSP Alternate (see port 554)
http://www.cs.columbia.edu/~hgs/rtsp/

Categories

Resources