ioctl (TUNSETIFF) : device or resource busy - networking

I am unable to set TUN interface. Everywhere i searched and it says the device should be rooted.
I am setting up proxyserver on my ubuntu 14.04 system
static int get_interface(char *name) {
int interface = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(interface, TUNSETIFF, (void *)&ifr) < 0) {
perror("Cannot get TUN interface");
exit(1);
}
return interface;
}

Check your device name (i.e. ifr.ifr_name). Another process maybe using the same device. For example, you may be trying to use tun0 and another process has it open already.

Related

printf alternative when using "define _GNU_SOURCE"

After reading https://www.quora.com/How-can-I-bypass-the-OS-buffering-during-I-O-in-Linux I want to try to access data on the serial port with the O_DIRECT option, but the only way I can seem to do that is by adding the GNU_SOURCE define but when I tried to execute the program, nothing at all is printed on the screen.
If I remove "#define _GNU_SOURCE" and compile, then the system gives me an error on O_DIRECT.
If I remove the define and the O_DIRECT flag, then incorrect (possibly outdated) data is always read, but the data is printed on the screen.
I still want to use the O_DIRECT flag and be able to see the data, so I feel I need an alternative command to printf and friends, but I don't know how to continue.
I attached the code below:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#define TIMEOUT 5
int main(){
char inb[3]; //our byte buffer
int nread=0; //number bytes read from port
int n; //counter
int iosz=128; //Lets get 128 bytes
int fd=open("/dev/ttyS0", O_NOCTTY | O_RDONLY | O_SYNC | O_DIRECT); //Open port
tcflush(fd,TCIOFLUSH);
for(n=0;n<iosz;n++){
int s=time(NULL); //Start timer for 5 seconds
while (time(NULL)-s < TIMEOUT && nread < 1){
inb[0]='A'; //Fill buffer with bad data
inb[1]='B';
inb[2]='C';
nread=read(fd,(char*)inb,1); //Read ONE byte
tcflush(fd,TCIOFLUSH);
if (nread < 0 || time(NULL)-s >= TIMEOUT){
close(fd); //Exit if read error or timeout
return -1;
}
}
printf("%x:%d ",inb[0] & 0xFF,nread); //Print byte as we receive it
}
close(fd); //program ends so close and exit
printf("\n"); //Print byte as we receive it
return 0;
}
First off, I'm no expert on this topic, just curious about it, so take this answer with a pinch of salt.
I don't know if what you're trying to do here (if I'm not looking at it the wrong way it seems to be to bypass the kernel and read directly from the port to userspace) was ever a possibility (you can find some examples, like this one but I could not find anything properly documented) but with recent kernels you should be getting an error running your code, but you're not catching it.
If you add these lines after declaring your port:
...
int fd=open("/dev/ttyS0", O_NOCTTY | O_RDONLY | O_SYNC | O_DIRECT );
if (fd == -1) {
fprintf(stderr, "Error %d opening SERIALPORT : %s\n", errno, strerror(errno));
return 1;
}
tcflush(fd,TCIOFLUSH);
....
When you try to run you'll get: Error 22 opening SERIALPORT : Invalid argument
In my humble and limited understanding, you should be able to get the same effect changing the settings on termios to raw, something like this should do:
struct termios t;
tcgetattr(fd, &t); /* get current port state */
cfmakeraw(&t); /* set port state to raw */
tcsetattr(fd, TCSAFLUSH, &t); /* set updated port state */
There are many good sources for termios, but the only place I could find taht also refers to O_DIRECT (for files) is this one.

qt read data from serial port just after open by another program

I'm using Qt version 5.5.1 from windows 8.1.
When I run qtserialport terminal example,
program connects to port successfully, but does not receive any data.
But when I close this program and open Hercules_3-2-6 Application (rs232 terminal software), that application read data,
and after close Hercules_3-2-6 application and open terminal example again, this program works and reads data until restarting computer.
I repeat this process many times.
But terminal project does not receive any data after restarting system until port opens one time by Hercules_3-2-6 Application.
Specification of port:
Name: COM3,
Baud Rate: 9600,
Data bits: 8,
Parity: None,
Stop bits: 1,
Flow control: None
void MainWindow::openSerialPort()
{
SettingsDialog::Settings p = settings->settings();
serial->setPortName(p.name);
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
if (serial->open(QIODevice::ReadWrite)) {
console->setEnabled(true);
console->setLocalEchoEnabled(p.localEchoEnabled);
ui->actionConnect->setEnabled(false);
ui->actionDisconnect->setEnabled(true);
ui->actionConfigure->setEnabled(false);
showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
.arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
.arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
} else {
QMessageBox::critical(this, tr("Error"), serial->errorString());
showStatusMessage(tr("Open error"));
}
}
void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
}
Simply you must configure serial port after that you have open it. If you open the port after these instruction:
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
they was ignored. Your second program configure right the serial port for you and the configuration remain when you start your program.
Try this:
void MainWindow::openSerialPort()
{
SettingsDialog::Settings p = settings->settings();
serial->setPortName(p.name);
if (serial->open(QIODevice::ReadWrite)) {
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
console->setEnabled(true);
console->setLocalEchoEnabled(p.localEchoEnabled);
ui->actionConnect->setEnabled(false);
ui->actionDisconnect->setEnabled(true);
ui->actionConfigure->setEnabled(false);
showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
.arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
.arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
} else {
QMessageBox::critical(this, tr("Error"), serial->errorString());
showStatusMessage(tr("Open error"));
}
}
void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
}
You must pay attention when configuring a serial port, any option can return true or false; best practice want to check and manage every error that can be returned.

iptables netfilter copying the packet

I was wondering if there is a way to copy a packet using iptables/netfilter, change it and deliver both to the application.
Basically, I want to capture a packet from a flow and redirect it to some queue, then I want to copy it, issue the verdict for it(I know how to do this part in C),then I need to change something in the copied version, AND issue the verdict for that "modified" packet too.
Basically I want the app to receive both the unmodified and the modified version.
Is this possible?
Thanks in advance for any help.
Your mission can be achieved with libipq library. The tutorial in following like focus on copying & modifying a packet in userspace.
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.205.2605&rep=rep1&type=pdf
You need to know C to work on it. Alternatively "Scapy" - a python based packet maipulation tool can be used.
#include <linux/netfilter.h>
#include <libipq.h>
/*
* Used to open packet ; Insert a iptables rule to get packet here
* iptables -I 1 [INPUT|OUTPUT|FORWARD] <packet header match> -j QUEUE
*/
#include <linux/netfilter.h>
#include <libipq.h>
#include <stdio.h>
#define BUFSIZE 2048
static void die(struct ipq_handle *h)
{
ipq_destroy_handle(h);
exit(1);
}
int main(int argc, char **argv)
{
int status;
unsigned char buf[BUFSIZE];
struct ipq_handle *h;
h = ipq_create_handle(0, NFPROTO_IPV4);
if (!h)
die(h);
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
if (status < 0)
die(h);
do{
status = ipq_read(h, buf, BUFSIZE, 0);
if (status < 0)
die(h);
if (ipq_message_type(buf) == IPQM_PACKET){
ipq_packet_msg_t *m = ipq_get_packet(buf);
status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
}
} while (1);
ipq_destroy_handle(h);
return 0;
}

libpcap fails to capture packets after upgrading to new linux ethernet driver

I have an old system running a custom 2.6.15 kernel that uses libpcap (version 1.1.1). Recently I've changed my network card with Intel 82575EB chipset that requires me to update the driver to igb.ko (was e1000.ko). After the update, libpcap stop capturing packets. I modified a sample test code from tcpdump website that captures 1 packet and print the header information, libpcap return header.len of 1358 and header.caplen of 42, whereas in e1000 case, both packet.len and packet.caplen returns 1358. I've tried disabling MSI/MSI-X and increase the MTU but nothing works. Is there any other options I need to set to get the igb driver to work with libpcap?
Here's the sample test program (courtesy of tcpdump/libpcap team):
#include <pcap.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
pcap_t *handle; /* Session handle */
char dev[20]; /* The device to sniff on */
char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
struct bpf_program fp; /* The compiled filter */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */
if (argc <= 1) return(1);
strcpy(dev, argv[1]);
/* Find the properties for the device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
net = 0;
mask = 0;
}
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return(2);
}
/* Grab a packet */
packet = pcap_next(handle, &header);
/* Print its length */
printf("packet length [%d]; captured length [%d]\n", header.len, header.caplen);
/* And close the session */
pcap_close(handle);
return(0);
}
Try libpcap 1.4.0, which is currently the most recent release; there's a bug in 1.1.1 that, as I remember, could cause a packet to be supplied with a too-short caplen even though you've supplied a sufficiently-large snapshot length argument to pcap_open_live() (which you have - BUFSIZ is typically somewhere between 1K and 4K, both of which are bigger than 42, and I think it's 4K on Linux).

iOS UDP broadcast vs. PHP UDP broadcast

I'm trying to send data via UDP to the network. I've got some PHP code running on my local machine which works:
#!/usr/bin/php -q
<?php
$socket = stream_socket_client('udp://225.0.0.0:50000');
for($i=0;$i<strlen($argv[1]);$i++) $b.="\0\0\0".$argv[1][$i];
fwrite($socket,$b,strlen($argv[1])*4);
fclose($socket);
?>
Gives me the output in tcpdump:
18:53:24.504447 IP 10.0.1.2.52919 > 225.0.0.0.50000: UDP, length 36
I'm trying to get to the same result on a remote iOS with the following code:
- (void)broadcast:(NSString *)dx {
NSData* data=[dx dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"Broadcasting data: %#", dx);
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in addr4client;
memset(&addr4client, 0, sizeof(addr4client));
addr4client.sin_len = sizeof(addr4client);
addr4client.sin_family = AF_INET;
addr4client.sin_port = htons(PORT);
addr4client.sin_addr.s_addr = htonl(INADDR_BROADCAST);
int yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void *)&yes, sizeof(yes)) == -1) {
NSLog([NSString stringWithFormat:#"Failure to set broadcast! : %d", errno]);
}
char *toSend = (char *)[data bytes];
if (sendto(fd, toSend, [data length], 0, (struct sockaddr *)&addr4client, sizeof(addr4client)) == -1) {
NSLog([NSString stringWithFormat:#"Failure to send! : %d", errno]);
}
close(fd);
}
Which gives me the following output in tcpdump:
19:01:22.776192 IP 10.0.1.4.60643 > broadcasthost.50000: UDP, length 9
Looks basically OK, but doesn't arrive in Quartz Composer for some reason, I guess there should be the IP address or something instead of 'broadcasthost'.
Any idea?
The problem was not in the implementation of the broadcaster, but the format of the string. To work with Quartz Composer, every character needs to be preceded by a backslash-zero combination: "\0\0\0", so "abc" has to be formatted and sent as "\0\0\0a\0\0\0b\0\0\0c".
See also Celso Martinho's blog article: Leopard’s Quartz Composer and Network events.
I suggest using AsyncSocket ( google it, its on googlecode ), very well tested objective-c code that runs on iOS.
That way you can send data really easy using a NSData object. AsyncSocket manages the hard part for you.
If that isn't an option for you you should use CFSocket. What you are doing is implementing code that has been written for you already, CFSocket.

Resources