macOS blocking serial I/O - macos

I'm writing a tool as part of a test suite, which needs to talk over a serial port to some hardware so that the code being tested sees the environment change.
So, I do this:
open("/dev/tty.usbmodem14141", O_RDWR | O_NOCTTY);
only it hangs there. If I replace that call with
open("/dev/tty.usbmodem14141", O_RDWR | O_NOCTTY | O_NONBLOCK);
then it works -- but I would prefer not to have to fiddle with select() and friends, or write a busy-loop poll, just so I can read from the serial port; that's what blocking I/O is for.
Do I need to do anything special for this to work?

When you have opened the serial terminal in nonblocking mode, you can then clear the file status flag to perform I/O in blocking mode.
To clear the nonblocking status flag you can use fcntl(), e.g.:
int flags;
flags = fcntl(fd, F_GETFL);
flags &= ~O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
Since the Linux version of F_SETFL can change only the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags, common practice is to simplify the code down to just
fcntl(fd, F_SETFL, 0);
(Yes, the single-liner does not have the same degree of portability as advocated in Setting Terminal Modes Properly.)

Related

Can't open RDP redirected serial port

I have a VM (Win10 x64) where my code runs, and my host is also Win10x64. I have an FTDI device connected to my host, and I need to use it with the guest. I have set up all (on both machines) to not prevent port redirecting. Port redirection seems to both work and not: it is not shown in the device manager albeit it looks to be there in all other places.
My code should be ok. It still fails on both COM2, \\.\COM2, and \\\\.\\COM2: it returns INVALID_HANDLE_VALUE and puts 'The system cannot find the file specified' in GetLastError.
HANDLE m_hCommPort = CreateFile( port ,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
(removing FILE_FLAG_OVERLAPPED makes no difference)
Even this works (I have no COM4, but I have COM2):
Is there an other syntax for redirected ports, or am I missing something?

RS232 serial port communication in kernelspace

I'm writing a kernel module for Linux v3.2 to control an external laser, but I'm having trouble communicating signals through the RS232 serial port on the machine.
There seems to be a serial driver already compiled in my kernel holding ownership to the ioport addresses I want to access:
# cat /proc/ioports | grep serial
02e8-02ef : serial
02f8-02ff : serial
03f8-03ff : serial
This makes sense since Linux allows userspace programs to use the /dev/ttyS* device nodes to communicate via the serial ports. For example, here's how I setup the device for an LCD panel:
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
...
/* Initialization and configuration */
const char *const lcd_dev = "/dev/ttyS1";
int lcd_dev_fd = open(lcd_dev, O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(lcd_dev_fd, F_SETFL, 0);
struct termios options;
tcgetattr(lcd_dev_fd, &options);
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_oflag &= ~OPOST;
tcsetattr(lcd_dev_fd, TCSANOW, &options);
...
/* sending bytes */
const unsigned char scls[] = {0xFE, 'X', 0xFE, 75, 0xFE, 84, 0xFE, 'H'};
write(lcd_dev_fd, scls, sizeof(scls);
However, this is a userspace interface and thus incompatible with my kernelspace module. I need a way to produce the same effect (RS232 serial I/O) but from within kernelspace.
Although I can unload the default Linux serial driver and replace it with my own custom RS232 driver, I don't want to reinvent the wheel here -- the default Linux serial driver appears to support the functionality I require.
Is there a simple way to communicate via the RS232 serial ports in kernelspace (perhaps through this default Linux serial driver), or do I just have to program my own custom RS232 driver?
Take a look at line disciplines. You can use it to attach a tty device to some read and write routines defined in kernelspace and thus write a driver using a serial line. The line discipline gets attached to it from user space and the kernel will do all the rest.
A good example is slcan (drivers/net/can/slcan.c). Examples for the libc calls handling this can be found in can-utils (https://gitorious.org/linux-can/can-utils). If you prefer working by book chapter 18 of Linux Device Drivers will give a good first step: http://www.makelinux.net/ldd3/chp-18, though the book is not very up to date. Some details may also be found at http://www.linusakesson.net/programming/tty/.

Read fails after tcpreplay with error: 0: Resource temporarily unavailabl

I have a very simple script to run. It calls tcpreplay and then ask the user to type in something. Then the read will fail with read: read error: 0: Resource temporarily unavailable.
Here is the code
#!/bin/bash
tcpreplay -ieth4 SMTP.pcap
echo TEST
read HANDLE
echo $HANDLE
And the output is
[root#vse1 quick_test]# ./test.sh
sending out eth4
processing file: SMTP.pcap
Actual: 28 packets (4380 bytes) sent in 0.53 seconds. Rated: 8264.2 bps, 0.06 Mbps, 52.83 pps
Statistics for network device: eth4
Attempted packets: 28
Successful packets: 28
Failed packets: 0
Retried packets (ENOBUFS): 0
Retried packets (EAGAIN): 0
TEST
./test.sh: line 6: read: read error: 0: Resource temporarily unavailable
[root#vse1 quick_test]#
I am wondering if I need to close or clear up any handles or pipes after I run tcpreplay?
Apparently tcpreplay sets O_NONBLOCK on stdin and then doesn't remove it. I'd say it's a bug in tcpreplay. To work it around you can run tcpreplay with stdin redirected from /dev/null. Like this:
tcpreplay -i eth4 SMTP.pcap </dev/null
Addition: note that this tcpreplay behavior breaks non-interactive shells only.
Another addition: alternatively, if you really need tcpreplay to receive your
input you can write a short program which resets O_NONBLOCK. Like this one
(reset-nonblock.c):
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int
main()
{
if (fcntl(STDIN_FILENO, F_SETFL,
fcntl(STDIN_FILENO, F_GETFL) & ~O_NONBLOCK) < 0) {
perror(NULL);
return 1;
}
return 0;
}
Make it with "make reset-nonblock", then put it in your PATH and use like this:
tcpreplay -i eth4 SMTP.pcap
reset-nonblock
While the C solution works, you can turn off nonblocking input in one line from the command-line using Python. Personally, I alias it to "setblocking" since it is fairly handy.
$ python3 -c $'import os\nos.set_blocking(0, True)'
You can also have Python print the previous state so that it may be changed only temporarily:
$ o=$(python3 -c $'import os\nprint(os.get_blocking(0))\nos.set_blocking(0, True)')
$ somecommandthatreadsstdin
$ python3 -c $'import os\nos.set_blocking(0, '$o')'
Resource temporarily unavailable is EAGAIN (or EWOULDBLOCK) which is the error code for nonblocking file descriptor when no further data is available (would block if wasn't in nonblocking mode). The previous command (tcpreplay in this case) erroneously left STDIN in nonblocking mode. The shell will not correct it, and the following process isn't meant to work with non- default nonblocking STDIN.
In your script, you can also turn off nonblocking with:
perl -MFcntl -e 'fcntl STDIN, F_SETFL, fcntl(STDIN, F_GETFL, 0) & ~O_NONBLOCK'

Finding the address of /bin/bash for buffer overflow attack

I am trying out ret-to-libc attacks and use the following piece of code to get the address of environment variable /bin/bash
#include <unistd.h>
int main(void)
{
printf("bash address: 0x%lx\n", getenv("SHELL"));
return 0;
}
when i use gdb's x command to check if the address returned by this code is correct it shows up correctly the first time.But when some other program is executed this address changes automatically.What should i do to keep this environment variable's address constant? I am using this address for buffer overflow, but since it keeps changing with every run, the attack is never successful. Any suggestions?
You have to disable the ASLR for the address to not change.
echo 0 | tee /proc/sys/kernel/randomize_va_space

Profiling the memory used by linux kernel

I have linux kernel 2.6.30 on an ARM based embedded device.
I have to do some kernel memory usage profiling on the device.
I am thinking of monitoring the ps output on various kernel threads and modules while I carry out actions like wifi on/off etc.
Can you suggest me:
Which threads I need to monitor? How to monitor the kernel module memory usage?
sometimes it is useful to get the real info straight from the kernel, I have used this little C program I threw together to get real system info in an output format that is suited for the shell (it compiles down to a pretty small binary if that matters) --
#include <sys/sysinfo.h>
int main(int argc, char **argv){
struct sysinfo info;
sysinfo(&info);
printf( "UPTIME_SECONDS=%d\n"
"LOAD_1MIN=%d\n"
"LOAD_5MIN=%d\n"
"LOAD_15MIN=%d\n"
"RAM_TOT=%d\n"
"RAM_FREE=%d\n"
"MEMUSEDKB=%d\n"
"RAM_SHARED=%d\n"
"RAM_BUFFERS=%d\n"
"SWAP_TOT=%d\n"
"SWAP_FREE=%d\n"
"PROCESSES=%d\n",
info.uptime,
info.loads[0],
info.loads[1],
info.loads[2],
info.totalram,
info.freeram,
(info.totalram-info.freeram)*info.mem_unit/1024,
info.sharedram,
info.bufferram,
info.totalswap,
info.freeswap,
info.procs);
}
I use it in the shell like this:
eval `sysinfo`
BEFORERAM=$MEMUSEDKB
command &
sleep .1 #sleep value may need to be adjusted depending on command's run time
eval `sysinfo`
AFTERRAM=$MEMUSEDKB
echo RAMDELTA is $(($AFTERRAM - BEFORERAM ))

Resources