Get used ports and states - c

How can I get used ports and their states on Linux? Basically, everything that netstat can do, but in C?

Running strace on a run of netstat will show you the system calls it makes and their arguments.
$ strace netstat
...
open("/proc/net/tcp6", O_RDONLY) = 3
open("/proc/net/udp", O_RDONLY) = 3
...
This is often a good way to find out what a program is doing or the calls it makes and can sometimes be easier than looking at the source if all you need is to find out which call to look up on a man page.

Well, for “everything that netstat can do,” you could start with netstat itself. The source code is here:
http://net-tools.git.sourceforge.net/git/gitweb.cgi?p=net-tools/net-tools;a=blob;f=netstat.c;h=f046f09162689f258f8920c1c2af27e01cdc77f2;hb=HEAD
It should be noted that most of what netstat does, it obtains from the /proc filesystem; it looks like the *_do_one routines hold most of the "interesting" guts.

Related

posix_spawn pipe dmesg to python script

I've got several USB to 422 adapters in my test system. I've used FTProg to give each adapter a specific name: Sensor1, Sensor2, etc. They will all be plugged in at power on. I don't want to hard code each adapter to a specific ttyUSBx. I want the drivers to figure out which tty it needs to use. I'm developing in C for a linux system. My first thought was to something like this in my startup code.
system("dmesg | find_usb.py");
The python script would find the devices since each one has a unique Product Description. Then using the usb tree to associate each device with its ttyUSBx. The script would then create /tmp/USBDevs which would just be a simple device:tty pairing that would be easy for the C code to search.
I've been told...DoN't UsE sYsTeM...use posix_spawn(). But I'm having problems getting the output of dmesg piped to my python script. This isn't working
char *my_args[] = {"dmesg", "|", "find_usb.py", NULL};
pid_t pid;
int status;
status = posix_spawn(&pid, "/bin/dmesg", NULL, NULL, my_args, NULL);
if(status == 0){
if(waitpid(pid, &status, 0) != -1);{
printf("posix_spawn exited: %i", status);
}
I've been trying to figure out how to do this with posix_spawn_file_actions(), but I'm not allowed to hit the peak of the 'Ballmer Curve' at work.
Thanks in advance
Instead of using /dev/ttyUSB* devices, write udev rules to generate named symlinks to the devices. For a brief how-to, see here. Basically, you'll have an udev rule for each device, ending with say SYMLINK+=Sensor-name, and in your program, use /dev/Sensor-name for each sensor. (I do recommend using Sensor- prefix, noting the initial Capital letter, as all device names are currently lowercase. This avoids any clashes with existing devices.)
These symlinks will then only exist when the matching device is plugged in, and will point to the correct device (/dev/ttyUSB* in this case). When the device is removed, udev automagically deletes the symlink also. Just make sure your udev rule identifies the device precisely (not just vendor:device, but serial number also). I'd expect the rule to look something like
SUBSYSTEM=="tty", ATTRS{idVendor}=="VVVV", ATTRS{idProduct}=="PPPP", ATTRS{serial}=="SSSSSSSS", SYMLINK+="Sensor-name"
where VVVV is the USB Vendor ID (four hexadecimal digits), PPPP is the USB Product ID (four hexadecimal digits), and SSSSSSSS is the serial number string. You can see these values using e.g. udevadm info -a -n /dev/ttyUSB* when the device is plugged in.
If you still insist on parsing dmesg output, using your own script is a good idea.
You could use FILE *handle = popen("dmesg | find_usb.py", "r"); and read from handle like it was a file. When complete, close the handle using int exitstatus = pclose(handle);. See man popen and man pclose for the details, and man 2 wait for the WIFEXITED(), WEXITSTATUS(), WIFSIGNALED(), WTERMSIG() macros you'll need to use to examine exitstatus (although in your case, I suppose you can just ignore any errors).
If you do want to use posix_spawn() (or roughly equivalently, fork() and execvp()), you'd need to set up at least one pipe (to read the output of the spawned command) – two if you spawn/fork+exec both dmesg and your Python script –, and that gets a bit more complicated. See man pipe for details on that. Personally, I would rewrite the Python script so that it executes dmesg itself internally, and only outputs the device name(s). With posix_spawn(), you'd init a posix_file_actions_t, with three actions: _adddup2() to duplicate the write end of the pipe to STDOUT_FILENO, and two _addclose()s to close both ends of the pipe. However, I myself prefer to use fork() and exec() instead, somewhat similar to the example by Glärbo in this answer.

Catching Mach system calls using dtruss

I ran dtruss on vmmap that is a process that read the virtual memory of another remote process.
I would expect that some of mach_port system calls would appear in the output of my command, but couldn't trace any (i.e. mach_vm_read, task_for_pid, etc ..)
The exact command i ran (notice that dtruss is a wrapper script of dtrace in OS-X) :
sudo dtruss vmmap <pid_of_sample_process>
The input argument for vmmap is just a pid of any running process, and the OS version i use is 10.10 (in 10.11 there's entitlement issue when running dtruss on apple products such as vmmap).
Perhaps someone can tell me how to identify the system call i'm looking for... Should I look for the explicit name in dtruss output, or just a general call number of my desired syscall (sadly, i haven't found any of them) :
./bsd/kern/trace.codes:0xff004b10 MSG_mach_vm_read
It looks to me like it's not using Mach APIs. It's using the libproc interface. I'm seeing many proc_info() syscalls, which is what's behind library calls like proc_pidinfo().
I used:
sudo dtrace -n 'pid$target::proc_*:entry {}' -c 'vmmap <some PID>'
to trace the various libproc functions being called. I see calls to proc_name(), proc_pidpath(), and proc_pidinfo() to get information about the target process and then calls to proc_regionfilename() to get information about the VM regions.
By the way, vmmap doesn't read the memory of the other process, it just reports information about the VM regions, not their contents. So, I wouldn't expect to see mach_vm_read() or the like.

Performing the equivalent of chattr +i filename.txt from Linux application

Is there any interface in the Linux userspace API that will allow me to perform the action equivalent to
chattr +i myfile
chattr -i myfile
If possible I need to do this from within my application but I cannot find anything online that suggests how one would go about doing this from the Linux API. I would have thought there would be some kind of ioctl call available to do this but I simply cannot find any details about it.
have a look at:
http://www.danlj.org/lad/src/setflags.c.html
and if you do some strace on chattr, you could have found out that it calls stuff that looks like:
ioctl(fd, EXT2_IOC_SETFLAGS, flags)
(have a look at this thread)

what happens if an application open more than one connection to syslog?

I have an application that uses syslog for logging. another library within this application explicitly calls openlog() for its own usage, in this case something strange happens: stderr output is sent to a tcp socket I already opened.
When I change the lib's output log to stderr or stdout everything works fine.
I was wondering if this a problem with two syslog connection or is it just a mess-up somewhere in the code?
This is syslog initialisation of the main app:
openlog( "app", LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
This is syslog initialisation of the lib:
openlog("lib", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
It is probably implementation dependent. If you use MUSL libc the code is here in syslog.c an you can see that only one fd is used for syslog (so two openlog-s are sharing the same log_fd). Look into GNU libc source code to see what happens on most Linux implementations. You might also investigate with strace or ltrace

Echo value to Linux console

How can I, in C, output a value from a syscall to the Linux console so that it will be visible after a dmesg? What method do I use for printing?
You're looking for the printk() function; some documentation on the types that it supports is found in Documentation/printk-formats.txt. It is defined in kernel/printk.c.
I assume you mean in the user-space. You can write the string to /dev/kmsg. In shell, just echo it. In C, it would be also very easy.
[root#cr0 ~]# echo hello > /dev/kmsg
[root#cr0 ~]# dmesg | tail -1
[24156.408735] hello
But if you mean in kernel space, of course, you need to call printk().
In addition, you might be interested (even if that does not answer exactly your question), by the openlog & syslog functions. From within an application, they are the proper way to get system logging.

Resources