I am using SimplePing sample from Apple to ping to a host which successfully received a response from the framework delegate
func simplePing(pinger: SimplePing!, didReceivePingResponsePacket packet: NSData!)
Which I am struggled to find the way to to decode the packet data (e.g. get the host name, ip)
I know that it's something about CFNetwork but I just can't find the right way to read the data, hope someone can help.
If anyone stumble upon this topic in pesent, like me.
Host name or ip address can be found in pinger property. If that is what you looking for.
Example:
func simplePing(_ pinger: SimplePing, didReceivePingResponsePacket packet: Data, sequenceNumber: UInt16) {
print("Host: \(pinger.hostName)")
}
The sample provides a method called icmpInPacket: that returns a broken-out struct. Use that. :-)
Related
I want to use a UNIX socket on Macos using Swift to receive some bytes, nothing serious. But I can't get to
to read any data from the socket.
Why UNIX socket? I wanted to have a "simple IPC". I could use TCP/IP, but now I want to make this work.
I did create a socket using SocketPort
SocketPort(protocolFamily: AF_UNIX, socketType: SOCK_STREAM, protocol: 0, address: data)
I did created an input stream with:
(...)
CFStreamCreatePairWithSocket(kCFAllocatorDefault, port.socket, &readStream, nil)
(...)
self.inputStream = readStream!.takeRetainedValue()
self.inputStream?.delegate = self
self.inputStream?.schedule(in: RunLoop.current, forMode: .default)
self.inputStream?.open()
And after running the app, everything seems fine, even the StreamDelegate protocol function 'stream' is called
back with eventCode for 'openCompleted' after openning the input stream.
Then I send some data with 'socat' but can't get those bytes in the swift app.
I'm using XCode, I added the network entitlements as I read somewhere. But I can't debug the socket. I expected
the 'stream' function to get called once I send some data to the socket.
I read other projects like BlueSocket (I'll give a try later but is not simple to add it to my existing XCode proyect),
they seem to go low-level ( calling Darwin.socket, Darwin.connect...).
I can provide more code. I don't know where to look at. Any clue? advice?
Thanks!
I solved this years ago by writing my own implementation of URLProtocol. I was using it for Docker, so I added a URL scheme of "docker". The code has a lot of dependencies, but here is a a working commit where you should be able to get the basic idea.
I am interested in learning Vapor, so I decided to work on a website that displays government issued weather alerts. Alert distribution is done via a TCP/IP data stream (streaming1.naad-adna.pelmorex.com port 8080).
What I have in mind is to use IBM's BlueSocket (https://github.com/IBM-Swift/BlueSocket) to create a socket, though after this point, I gave it a bit of thought but was unable to come to a conclusion on what the next steps would be.
Alerts are streamed over the data stream, so I am aware the socket would need to be opened and listened on but wasn't able to get to much past that.
A few things with the data stream are that the start and end of an alert is detected using the start and end tags of the XML document (alert and /alert). There are no special or proprietary headers added to the data, it's only raw XML. I know some alerts also include an XML declaration so I assume the encoding should be taken into account if the declaration is available.
I was then thinking of using XMLParser to parse the XML and use the data I am interested in from the alert.
So really, the main thing I am struggling with is, when the socket is open, what would be the method to listen to it, determine the start and end of the alert and then pass that XML alert for processing.
I would appreciate any input, I am also not restricted to BlueSocket so if there is a better option for what I am trying to achieve, I would be more than open to it.
So really, the main thing I am struggling with is, when the socket is
open, what would be the method to listen to it, determine the start
and end of the alert and then pass that XML alert for processing.
The method that you should use is read(into data: inout Data). It stores any available data that the server has sent into data. There are a few reasons for this method to fail, such as the connection disconnecting.
Here's an example of how to use it:
import Foundation
import Socket
let s = try Socket.create()
try s.connect(to: "streaming1.naad-adna.pelmorex.com", port: 8080)
while true {
if try Socket.wait(for: [s], timeout: 0, waitForever: true) != nil {
var alert = Data()
try s.read(into: &alert)
if let message = String(data: alert, encoding: .ascii) {
print(message)
}
}
}
s.close()
First create the socket. The default is what we want, a IPv4 TCP Stream.
Second connect() to the server using the hostname and port. Without this step, the socket isn't connected and cannot receive or send any data.
wait() until hostname has sent us some data. It returns a list of sockets that have data available to read.
read() the data, decode it and print it. By default this call will block if there is no data available on the socket.
close() the socket. This is good practice.
You might also like to consider thinking about:
non blocking sockets
error handling
streaming (a single call to read() might not give a complete alert).
I hope this answers your question.
I am using dpkt to parse packets sniffed by Wireshark.
Here is my code:
for ts,buf in pcap:
try:
eth=dpkt.ethernet.Ethernet(buf)
except(dpkt.dpkt.NeedData,dpkt.dpkt.UnpackError):
continue
However, it seems that eth class cannot handle 802.11.
As Grant Garrison so eloquently noted in comments, 802.11 is not Ethernet. You'll want to try the dpkt.ieee80211.IEEE80211 class of dpkt to parse that packet.
Is there a way of getting the IP address/port of an incoming request? (I don't want the data in the message, but I'd like information from the SIP stack itself, and preferably also the listening point the request had been received on.)
So far I have not find any solution by parsing the Javadocs.
Pending you are using http://java.net/projects/jsip
Cast RequestEvent to gov.nist.javax.sip.RequestEventExt in
public void processRequest(RequestEvent requestEvent) {
RequestEventExt requestEventExt = (RequestEventExt) requestEvent;
requestEventExt.getRemoteIpAddress();
requestEventExt.getRemotePort();
}
Best Regards
Jean
I need to get the whole message(response), but socket.ReceiveBytes(); returns just part of the message. I tried to loop it but it fails on timeout when no bytes to receive.
List<byte> lb = new List<byte>();
byte[] receivedMsg = socket.ReceiveBytes();
while (receivedMsg.Length > 0)
{
lb.AddRange(receivedMsg);
receivedMsg = socket.ReceiveBytes();
}
So, how I can check if there are byte to read? How I can read the whole message?
Since its a Chilkat implementation, you should probably contact the developer. But I found this that could help: http://www.cknotes.com/?p=302
Ultimately, you need to know how much to read from the socket to constitute a whole message. For example, if the overlying protocol is a portmapper, then you know that you are expecting messsages in the format that the RFC specifies (http://tools.ietf.org/html/rfc1833.)
If you are rolling your own protocol over a socket connection, then use the method in the Chilkat blog post about putting the size of the total message in the first 4 bytes.