Cocoa Monitor Packets On Ports - macos

I want to monitor packets on specific ports in Mac OS X. Being able to read their contents and sometimes changing their contents (if possible). I was wondering if it's possible by writing a KEXT or can I do this in an application and showing results instantly. I would appreciate any information on libraries and approaches I can use to achieve this.

"Monitor packets" in what sense?
If you mean "watch what packets to or from specific TCP or UDP ports are sent" or "what packets are sent or received on particular network interfaces", you would use the pcap library, just as on other UN*Xes. libpcap/WinPcap is the library that Wireshark - and tcpdump - use; on OS X, the underlying kernel mechanism it uses is BPF (the Berkeley Packet Filter), which is built into XNU (it is open-source - see the bsd/net/bpf.c and bsd/net/bpf_filter.c files, and the header files they include, in the XNU source) and doesn't require a kext. (Wireshark does not have its own kext; it uses libpcap/WinPcap so that it can work on Linux and OS X and *BSD and Solaris and HP-UX and AIX and Tru64 UNIX and IRIX and so on, as well as on Windows if WinPcap is installed, so, on OS X and *BSD, it ultimately uses BPF.)
Libpcap/WinPcap doesn't, except on Linux, allow you to capture on all interfaces with one "handle"; you would have to use pcap_findalldevs() to find all the currently-available interfaces, and then open separate handles for each of them. If by "ports" you mean "network ports", so that one "port" is your Ethernet port and another is your Wi-Fi adapter, you'd have to individually open all the "ports" on which you want to capture.
If by "ports" you mean TCP or UDP ports, and you only want to watch traffic to or from particular ports, you'd have to specify a "filter" expression, translate it to "BPF code" with pcap_compile(), and then make it the filter for a particular libpcap/WinPcap handle with pcap_setfilter().
If you want to use a Cocoa wrapper for pcap, a Google search I did a while ago found packetsniffer and CapKit; I have not used either of those, so I can't recommend one or the other.

Have you seen Apple's overview documentation on Network Kernel Extensions? That should get you started.
The downloadable source code for this book also contains a few packet filtering example NKEs at various levels of the network stack. (The book of course also explains this stuff in some detail in chapter 13)
You also may be able to re-use an existing open source kext for pure monitoring: The Wireshark application already does this, and you should be able to hook into its kext. For actually modifying the packet stream, you will probably have to do that purely in the kernel.

Because OS X and iOS are Unix and Objective-C is C, the answer is, "the same way you do it on Unix in C" - Cocoa is high-level and what you want to do is low level. I can't find the question on SO but someone suggested looking at the source for MenuMeters as an example of network monitoring.

Related

Can USB-OTG be used for U-Boot and Linux consoles?

I have a custom i.MX6Q-based board with working U-Boot and Linux (Ubuntu) setups. The micro and board have support for USB-OTG and one serial port; currently, the serial port serves the console for both U-Boot and Linux. However, we may need to use the serial port for another purpose, but we don't want to lose the console for U-Boot and Linux. Is it possible to use the USB-OTG port for the system console for both U-Boot and Linux?
I've done some research and found a couple of promising articles here and here, though the second article says this tidbit:
Unfortunately it won't work as system console as the gadget driver is loaded as a module, but we can use it for serial console.
I'm not sure I understand this, but it sounds like the method won't meet my needs, which is to use USB-OTG for both U-Boot and Linux system consoles. I did try these methods, but without luck, which may mean that U-Boot and Linux aren't built properly for the desired functionality.
So here are my questions:
Can this work for U-Boot?
Can this work for Linux?
Am I insane for contemplating this path?
For either, any guidance (e.g. tutorials, examples, etc.) would be greatly appreciated.
Thanks!
Can this work for U-Boot?
Yes, at least since U-Boot version 2008.10, the README file has stated:
Define the below if you wish to use the USB console.
CONFIG_USB_DEVICE
Define this to build a UDC device
CONFIG_USB_TTY
Define this to have a tty type of device available to
talk to the UDC device
CFG_CONSOLE_IS_IN_ENV
Define this if you want stdin, stdout &/or stderr to
be set to usbtty.
Note that these configuration symbols are not accessible using the menuconfig, and must be enabled in a configuration file.
Currently at least five boards use this U-Boot capability, based on the occurrence of CONFIG_USB_TTY in files in include/configs/, for example include/configs/ti_omap4_common.h.
This USB configuration requires non-default definitions for the stdin and stdout environment variables. Refer to the README documentation for the details.
Can this work for Linux?
Yes, Linux (at least since version 4.5) can have a serial console on a USB connection, either a USB-to-serial adapter on a host port or a USB serial gadget on a device port (using CDC/ACM).
For instance, in drivers/usb/gadget/Kconfig there's the selection:
config U_SERIAL_CONSOLE
bool "Serial gadget console support"
depends on USB_G_SERIAL
help
It supports the serial gadget can be used as a console.
In the Linux 5.7.8 kernel only two boards have default configurations that use this capability, for example see arch/arm/configs/aspeed_g4_defconfig.
Besides a proper configuration to build the necessary drivers, a serial-gadget console requires (1) the kernel parameter specification (e.g. console=ttyGS0,...), and (2) a login session initiated by a getty command (e.g. in the inittab file).
Am I insane for contemplating this path?
No comment.
Beware that should you encounter a kernel boot issue, the Linux serial-gadget console does not support earlycon nor earlyprintk capability.
Personally I prefer to use a serial link that is persistent regardless of the target board's state. That ensures the terminal emulator program does not complain about lost connections.
Addendum
Unfortunately this Linux console on a USB serial gadget does not display boot messages generated by the kernel (before the login prompt), even if all drivers are statically linked in to the kernel image.
Although the syslog has messages like
console [ttyGS0] enabled
g_serial gadget: g_serial ready
...
gs_open: ttyGS0 ((ptrval),(ptrval))
before the salient Freeing unused kernel memory message, the host side does not receive any console messages until userspace is active.
This shortcoming is also reported in this guide: https://linux-sunxi.org/USB_Gadget/Serial

Can a user application on macOS receive raw ethernet packets?

Can a user application on macOS receive raw ethernet packets? I have a piece of hardware that uses it's own custom ethernet protocol and has it's own ether type defined. Is there anyway I can create a user application that sends / receives these packets? Mac OS does not support AF_PACKET. I believe Berkeley Packet Filter requires root access. Are there any other options?
Install libpcap library - https://formulae.brew.sh/formula/libpcap
Then you could sniff and/or inject arbitrary packets.
Can a user application on macOS receive raw ethernet packets?
Yes. See, for example, /usr/sbin/tcpdump.
I believe Berkeley Packet Filter requires root access.
Yes, by default; that's what the "launch daemon that adjusts capture permissions at system startup" provided by Wireshark does (it's based on stuff from the libpcap source distribution) - it makes the BPF devices readable and writable by a group, so if your code runs with that group as one of the groups in its group set, it can read (capture) and write (transmit) on BPF devices.
Are there any other options?
PF_NDRV sockets might work. See, for example, this chapter from a macOS/iOS/etc. internal book and this StackOverflow answer.
Install libpcap library
Note that libpcap ships as part of macOS, and the headers ship as part of the macOS SDK, so that, on macOS, you can build programs that use it without installing anything other than Xcode (or the Xcode Command Line Tools), just as you can, on Linux, build programs that use libpcap without installing anything other than a compiler and your distribution's libpcap "developer package", and you can, on *BSD, build it without having installed anything other than whatever the installer says you need for developing software (it might even install the compiler/linker and the appropriate headers by default).

Is linux suggest us use sysfs or udev?

While we want to create a device file in file system, which one should we choose right now? Make a node in udev, which will show up in /dev or use sysfs which will show up in /sys.
I just think I can accomplish most of functions for a device through these two different ways. So it confused me a lot.
Thanks.
Use udev (and or define and publish some major & minor device numbers, like for mknod). See makedev(3)
Application programs want to access physical devices in /dev/ (not in /sys/). Data to/from a device go usually thru /dev/ char or block devices. Metadata and configuration can go thru sysfs
Read more about udev and about sysfs. See also device file wikipage.
You won't get very useful answers if you don't explain more concretely your issues... What exact kind of device are you thinking about? Very probably there exist already similar devices....
Publish very early (even in alpha stage, when it is not fully working) your device driver and software source code as free software preferably as GPLv2 (the license used by Linux kernel). Ask also on kernelnewbies. Work hard (perhaps more than a year) to get your driver incorporated in the official Linux kernel.
You should be familiar with Advanced Linux Programming (in the application userspace world) before attempting to code a kernel driver. After that, read books and resources on Linux kernel driver programming and study the source code of existing drivers in the recent Linux kernels.

USB linux gadget zero driver communicate with Windows host

I need to set up USB communication between a Windows 7 host and a Linux device for data transfer. I was able to compile the Linux kernel on the device to include the Gadget Zero driver in the kernel (not as a loadable module - Linux version 3.0.15). My project has some requirements, which also explains why I chose Gadget Zero:
1) On the Windows 7 host, a kernel mode driver must be used to communicate over the USB connection for sending and receiving bulk data. (speed is not important, not a lot of data at once).
2) On the linux device, no requirements on USB side except send and receive data easily over USB link. The data received will eventually be "unmarshalled" to call functions in another kernel module (and those responses packaged and sent back to the host).
3) Multiple linux devices will be connected to the host, so need easy way to enumerate connected devices and communicate with them.
So due to the requirements, I decided against the Gadget Serial. I'm having serious issues sending and receiving data over the virtual COM port in kernel mode (KMDF) in Win 7 host. WinUSB does not seem to want to open my attached device (I'm using KMDF windows USB driver from template in VS2012) Also, the gadget serial driver on the linux side, I cannot find the functions where the data is received and sent. Plus, any received data on the linux device seems to be echoed back to the host for some reason. (and to test this, I wrote a simple user-mode app in Windows, which is a no-no for my project).
Gadget Zero, it appears much simpler on the linux side. I can plug the USB cable to the Win7 host, and I can get the device to appear in the device manager. However, again I am having problems with getting communication going over the link. Gadget Zero has 2 bulk endpoints, so this shouldn't be an issue. Surely, someone has made data communication possible between a Windows host and a linux device using Gadget Zero? With Gadget Zero, it should be easy to enumerate the connected linux devices and communicate with them.
The trick is to keep the Windows side communication in kernel mode. Can someone point me in the right direction perhaps with Gadget Zero, Windows 7 KMDF, and some sample source code? I have a hard time believing no one has done this before because my internet searches don't turn up much. (and mostly user-mode solutions with Gadget Serial).
Thanks!
So you're writing a Win32 driver in which you want to communicate with your linuxed usb? I haven't written much win32 kernel code, but I believe I've seen a huge section in the doc, saying something like "This is how you make usb drivers"... That'd be it. In other words, when in kernel mode you have access to the full kernel usb layer. You don't need an existing driver or whatnot.
On the linux side you can use the serial gadget, in a different run mode. Only the default run mode, registers it self as VCP. There exist a more basic mode:
modprobe g_serial use_acm=0
Give it your own vendor id and you'll be able to attach your very own custom win32 driver. The 'multiple linux devices' will be handled by Windows. (Multiple instances of your driver, will be initiated.)
The echo you're seeing btw, is most likely a terminal feature. (The terminal mode on uarts will echo.) You have to disable it, when connecting. And now that you're at it, you also have to disable the xon/xoff, esc chars etc. (Standard legacy rubbish.)
And another thing. I'm not sure the gadget zero actually sends the data onto the line. It's meant for testing the gadget framework. (I could be mistaken though.)
Anyway, you've prolly solved this issue years ago. I'd be nice to know what you came up with.

Best way for a Mac application to talk to Windows applications

I need to write an app on Mac OS X that would send remote command to Windows applications to perform some tasks. The computers will be sitting on the same subnet and the Mac and Windows computers all have a fixed IP.
The data sent over really are just some string or boolean parameters so that the Windows app can perform specific tasks.
Someone will be writing the Windows app and I will be writing the Mac app.
I can find in the developer's doc about Mac to Mac communication, but nothing about what I need.
What's the best way to achieve this? What protocol is best suited for this?
Take a look at the Bonjour SDk for Mac and Windows: http://developer.apple.com/opensource/
There are (at least) two separate problems here:
#1 is how you discover the other app. Bonjour is one possibility, as is a local broadcast, as is explicitly configuring the hostname of the peer
#2 is how you talk to the other machine once you find it. For that part, I would suggest:
a) use TCP instead of UDP (in most cases), so you don't have to worry about retransmissions & sequencing
b) rather than inventing your own client-server protocol on top of TCP, use an existing one. I hear there's something called "HTTP" that's starting to catch on...
Could you just use UDP to broadcast a message out to the network? Your apps (regardless of whether they are running on Mac or Windows) can listen for the message and process them as needed.

Resources