calculator using ioctl of linux device driver - linux-device-driver

I am learning linux device drivers
So i am trying to write a code for calculator where user will give input using userspace program but the calculations will happen in kernel
I am using ioctl to pass values to kernel
It works fine first time(i.e. after inserting the device driver) ,but after that it gives incorrect output. So if i again want correct answer i do rmmod driver and again insmod driver
Whats wrong with the code ?
Is there any better way to map operation ,value1 and value2 than using the count variable as i am using in driver code
following is the output
where first time i get the correct output,but the second time a garbage value:
calculator_ioctl$ ./a.out
*************************************
Opening Driver
Operation to perform
1. Add
2. Subtract
3. Multiply
4. Divide
2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is 34
closing driver
calculator_ioctl$ ./a.out
*************************************
Opening Driver
Operation to perform
1. Add
2. Subtract
3. Multiply
4. Divide
2
Enter first value :45
Enter second value :11
writing value to driver
Reading value from driver
value is -1410510832
closing driver
driver code:
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kdev_t.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/device.h>
#include<linux/slab.h> //kmalloc.h
#include<linux/uaccess.h> //copy to/from user
#include<linux/ioctl.h>
#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)
int32_t value1 = 0 ;
int32_t value2 = 0 ;
int32_t value = 0 ;
int32_t oper = 0 ;
dev_t dev=0;
static struct class *dev_class;
static struct cdev etx_cdev ;
static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);
static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg);
static struct file_operations fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = etx_ioctl,
};
static long etx_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
static int count = 0;
switch(cmd) {
case WR_VALUE:
if(count == 0)
{
copy_from_user(&oper,(int32_t*)arg,sizeof(oper));
printk(KERN_INFO "oper = %d\n",oper);
break;
}
else if(count == 1){
copy_from_user(&value1,(int32_t*)arg,sizeof(value1));
printk(KERN_INFO "value1 = %d\n",value1);
break;
}
else if(count == 2){
copy_from_user(&value2,(int32_t*)arg,sizeof(value2));
printk(KERN_INFO "value2 = %d\n",value2);
break;
}
case RD_VALUE:
if(oper == 1)
value = value1 + value2 ;
else if(oper == 2)
value = value1 - value2;
else if(oper == 3)
value = value1 * value2;
else if(oper == 4)
value = value1 / value2;
else
break;
copy_to_user((int32_t*) arg, &value,sizeof(value));
break;
}
count+=1 ;
if(count == 3)
count = 0 ;
return 0;
}
static int __init etx_driver_init(void)
{
if((alloc_chrdev_region(&dev,0,1,"etx_dev")) <0){
printk(KERN_INFO"cannot allocate major number\n");
return -1;
}
printk(KERN_INFO " MAJOR = %d Minor = %d\n",MAJOR(dev),MINOR(dev));
cdev_init(&etx_cdev,&fops);
if((cdev_add(&etx_cdev,dev,1)) < 0){
printk(KERN_INFO "cannot add device to the system\n");
goto r_class;
}
/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct class\n");
goto r_class;
}
/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device 1\n");
goto r_device;
}
printk(KERN_INFO "Device Driver Insert...Done!!!\n");
return 0;
r_device:
class_destroy(dev_class);
r_class:
unregister_chrdev_region(dev,1);
return -1;
}
void __exit etx_driver_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
cdev_del(&etx_cdev);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Device Driver Remove...Done!!!\n");
}
module_init(etx_driver_init);
module_exit(etx_driver_exit);
MODULE_LICENSE("GPL");
application:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
#define WR_VALUE _IOW('a','a',int32_t*)
#define RD_VALUE _IOR('a','b',int32_t*)
int main()
{ int num;
int fd;
int32_t value,number1,number2,output,operation;
printf("\n*************************************\n");
printf("\nOpening Driver\n");
fd = open("/dev/etx_device",O_RDWR);
if(fd<0) {
printf("Cannot open device file ...\n");
return 0;
}
printf("Operation to perform\n\n");
printf("\
1. Add \n \
2. Subtract \n \
3. Multiply \n \
4. Divide \n\n\n ");
scanf("%d",&num);
if(num > 4 && num < 1)
{
printf("Enter between 1 and 4");
return 0;
}
ioctl(fd,WR_VALUE,(int32_t*) &num);
printf("Enter first value :");
scanf("%d",&number1);
printf("Enter second value :");
scanf("%d",&number2);
printf("writing value to driver\n");
ioctl(fd,WR_VALUE,(int32_t*) &number1);
ioctl(fd,WR_VALUE,(int32_t*) &number2);
printf("Reading value from driver \n");
ioctl(fd,RD_VALUE,(int32_t*)&value);
printf("value is %d\n",value);
printf("closing driver\n");
close(fd);
}

Related

low cpu-usage way to monitor connection to localhost

It seems a nonblocking connect to localhost always fails right away then poll() returns immediately with POLLIN flag set in revents. That prevents CPU enter a blocking state and the entire system runs in quite high cpu usage.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1470 panruoc+ 20 0 12956 1956 1820 S 26.2 0.0 2:09.49 zz1
Any suggestion is appriciated.
Here is my code of testing
int main(int argc, char *argv[])
{
struct sockdesc {
char *host;
int port;
int sockfd;
};
struct sockdesc sdes[] = {
{"localhost", 6000},
{"111.206.239.212", 6000},
};
unsigned int i;
for(i = 0; i < 2; i++) {
tcp_connect(sdes[i].host, sdes[i].port, &sdes[i].sockfd);
printf("sockfd = %d, %d\n", sdes[i].sockfd, errno);
}
if(!nonblocking)
return 0;
struct pollfd pollfds[2];
pollfds[0].fd = sdes[0].sockfd;
pollfds[1].fd = sdes[1].sockfd;
pollfds[0].events = POLLIN;
pollfds[1].events = POLLIN;
int conns;
for(conns = 0; conns != 3; ) {
int nfds = poll(pollfds, 2, -1);
if(nfds <= 0)
exit(1);
for(i = 0; (int)i < nfds; i++) {
if(pollfds[i].revents) {
if(pollfds[i].revents & POLLIN)
conns |= i;
printf(" fd = %d, revents = 0x%04x\n", sdes[i].sockfd, pollfds[i].revents);
}
}
}
return 0;
}
BR, Ruochen
Your for-loop looks suspicious:
for(conns = 0; conns != 3; ) {
When does conns ever become three?
It seems like your intent is here:
if(pollfds[i].revents & POLLIN)
conns |= i;
But if i is 0 for the first socket, conns |= i will not change the value.
And when both sockets have data available, your poll call will start returning immediately, but you are stuck in an infinite loop. Hence, high cpu overhead.
It appears your code's intent is to stay in a loop until both sockets have data available to read. Then break out of the loop then. So I suspect you really meant this:
conns |= (i+1);
There's other problems as well. poll returns the number of valid socket descriptors. Hence this line;
for(i = 0; (int)i < nfds; i++) {
So if the socket associated with pollfds[1] has data available, nfds will only be 1. Hence, your loop will only evaluate if pollfds[0] has data.
Let's clean your code up:
int ready_set = 0x00;
int all_ready_set = 0x03;
int num_sockets = 2;
while (ready_set != all_ready_set)
{
int nfds = poll(pollfds, 2, -1);
if(nfds <= 0)
{
// I would not actually exit. If a socket gets closed locally, you would have a valid and expected error, but maybe that can't happen in your program
exit(1);
}
for (i = 0; i < num_sockets; i++)
{
if (pollfds[i].revents & POLLIN)
{
int mask = 0x01 << i;
pollfds[i].events = 0; // stop listening for events on this socket
ready_set |= mask;
}
}
}

Go back N protocol implememtation

I am implementing Go back N protocol in C.I keep a char buffer and append the header informationa and data and send it to the server from the client process.
When I keep window size less than 10, the sequence number takes the value 1-9and occupies only one byte in the buffer. When the window size is >= 10 , sequence number may 1 or 2 bytes in the character array. So I am appending length of sequence number also as a header information. That time I am getting some random data written in the output file at the server. Whereas for window size less than 10 I coded without adding sequence no. length info. Everything works fine that time.
The codes are quiet exhaustive. Yet,
Can anybody suggest any corrections to be made in the code?
client code for window size 10:-
#include<stdio.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<time.h>
#include<sys/time.h>
unsigned short int checksum_2(void *buffer,unsigned int len,unsigned short int seed)
{
unsigned char *buf1 = (unsigned char*)buffer;
int i;
for(i=0;i<len;i++)
{
seed+=(unsigned int)(*buf1++);
}
//fold 32-bit sum to 16 bit
while(seed>>16)
seed = (seed & 0xFFFF)+ (seed>>16);
return seed;
}
unsigned short int checksum(unsigned char * buff,unsigned int count)
{
register unsigned int sum = 0;
//main summing loop
while(count >1)
{
sum += *((unsigned short int*) buff);
(buff)++;
count = count -2;
}
//add left over byte if any
if(count>0)
{
sum += *((unsigned char *)buff);
}
//fold 32-bit sum to 16 bit
while(sum>>16)
sum = (sum & 0xFFFF)+ (sum>>16);
return (~sum);
}
char* rand_corrupt(unsigned char* buff)
{
int n = strlen(buff);
char* str_temp = (char*)calloc(1,n); //allocate memory for a string
int i;
int num;
num = rand() %100;
if(num>95)
{
for(i=0;i<strlen(buff);i++)
{
buff[i] = buff[i]+1;
}
}
strcpy(str_temp,buff);
return str_temp;
}
char *itoa(long i,char *s,int dummy_radix)
{
sprintf(s,"%ld",i);
return s;
}
void rand_wait()
{
int num;
int i;
num = rand() %100;
if(num<5)
{
for(i=0;i<10;i++)
{
sleep(1);
}
}
return;
}
int
main (int argc, char **argv)
{
int sock,length,n;
struct sockaddr_in server,from;
struct hostent *hp;
long int packets =0;
clock_t t; //to measure CPU time
struct timeval start,end; //to measure actual execution time
struct timeval timer; //for the timer implementation
double time_diff;//to measure the timer for the execution time of code
unsigned short int check;
void* buff;
printf("initializing 2 d array\n");
char buf[1024][1024]={0};
printf("initialisation failed\n");
int nread[1024] = {0,};
char new_buff[65535]={0, };
char ack_buf[65535]={0, };
char* temp;
char checksum_info[1024]={0, } ;
char bytes_info[1024] = {0, } ;
unsigned short int bytes_len;
char bytes_len_str[1024]={0, };
char seqnum[10] = {0,};
int seq_no;
char current;
char data_1[75535]={0, };
unsigned short int check_length;
char check_len_str[1024]={0, };
char ack_check_len[1024]={0, };
unsigned short int ack_checksum_len;
char ack_check[65535]={0, };
unsigned short int ack_checksum;
char temp_buf[65535]={0, };
char temp_buffer[655]={0,};
unsigned short int actual_checksum;
unsigned short int length1;
char content[65535]={0, };
int i,j;
char end_flag =0; //to mark the end of file or error occured while reading file
int total_len[1024]={0,};
char data[1024][6553]= {0,};
char *tmp = NULL;
int msec,trigger;
clock_t difference,initial;
char ack_seqlen_char[8]= {0,};
int ack_seqlen;
int ack_seq;
char ack_seq_char[10] ={0,};
int seqnum_len;
char seqlen_char[10] = {0,};
t = clock();
gettimeofday(&start,NULL);
buff = calloc(1,1024);//allocating memory for message buffer
if(buff == NULL)
{
printf("memory allocation failedi\n");
return 1;
}
temp = calloc(1,65535); //allocating memory for new message
if(temp == NULL)
{
printf("memory allocation failed\n");
return 1;
}
// checking if hostname and the port address is provided //
if(argc!=3)
{
printf("insufficient arguments\n");
exit(1);
}
//create a socket//
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
{
printf("error in opening socket\n");
return 1;
}
//to get the hostname of the system or the machine//
hp= gethostbyname(argv[1]);
if(hp==0)
{
printf("Unknown host\n");
return 1;
}
//build the server's IP address //
bzero((char *)&server,sizeof(server));
bcopy((char*)hp->h_addr,(char *)&server.sin_addr,hp->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
length = sizeof(server);
/*open the file that we wish to transfer*/
FILE *fp = fopen("alice.txt","rb");
if(fp==NULL)
{
printf("file open error");
return 1;
}
fseek(fp,0,SEEK_END); //if exists read the size of the file
size_t file_size = ftell(fp);
fseek(fp,0,SEEK_SET);
printf("size of the file is %d\n", file_size);
/*find the number of packets*/
if(file_size == 0)
{
packets = 0;
}
else
{
packets = (file_size/1024)+1 ;
}
/*send the number of packets to the server*/
itoa(packets,(char*)buff,10);
printf("packets =%s\n",(char*)buff);
n= sendto(sock,buff,1024,0,(struct sockaddr *)&server,sizeof(struct sockaddr));
if(n<0)
{
printf("error in sending message to the server");
return 1;
}
int loop =1;
/*Read data from file and send it*/
int packetNum = 0;
int N = 10;
int base = 1;
int nextseqnum =1;
int sequence;
int seqnum_next = 1;
while(1)
{
while(nextseqnum<base+N) //send N consecutive packets
{
memset(buf[nextseqnum], 0, 65535); //clear the contents of buf before fread
memset(seqnum,0,10);
memset(seqlen_char,0,10);
memset(checksum_info,0,1024);
memset(check_len_str,0,1024);
memset(bytes_info,0,1024);
memset(bytes_len_str,0,1024);
memset(data[nextseqnum],0,6553);
/*First read file in chunks of 1024 bytes */
nread[nextseqnum] = fread(buf[nextseqnum],1,1024,fp);
printf("Bytes read %d\n",nread[nextseqnum]);
/*if read was success ,send data*/
if(nread[nextseqnum]>0)
{
printf ("I am HERE\n");
check = checksum(buf[nextseqnum],nread[nextseqnum]); //calculate the checksum
printf("checksum is %d\n",check);
itoa(check,checksum_info,10); //convert checksum into string
check_length = strlen(checksum_info); //calculate the length of the checksum
itoa(check_length,check_len_str,10); //convert the checksum lenght to string form
itoa(nread[nextseqnum],bytes_info,10); //the data length in string format
bytes_len = strlen(bytes_info);
itoa(bytes_len,bytes_len_str,10);
itoa(seqnum_next,seqnum,10); //combine seq no,checksum and the data content into one packet
printf("sequence number is %s\n",seqnum);
seqnum_len = strlen(seqnum); //getting the length of the sequence
itoa(seqnum_len,seqlen_char,10); //converting it into string format
strncat(data[nextseqnum],seqlen_char,strlen(seqlen_char));
strncat(data[nextseqnum],seqnum,strlen(seqnum));
strncat(data[nextseqnum],check_len_str,(strlen(check_len_str)));
strncat(data[nextseqnum],checksum_info,(strlen(checksum_info))); //adding checksum
strncat(data[nextseqnum],bytes_len_str,strlen(bytes_len_str)); //adding data length
strncat(data[nextseqnum],bytes_info,strlen(bytes_info)); //adding the data length info
j= seqnum_len+3+bytes_len+check_length;
for(i=0;i<nread[nextseqnum];i++)
{
data[nextseqnum][j] = buf[nextseqnum][i];
j++;
}
total_len[nextseqnum] = nread[nextseqnum]+3+bytes_len+check_length;//finding the total length
data[nextseqnum][total_len[nextseqnum]] = '\0';
n= sendto(sock,data[nextseqnum],total_len[nextseqnum],0,(struct sockaddr *)&server,sizeof(struct sockaddr));///send the data packet after adding the header info
if(n<0)
{
printf("error in sending message to the server");
fclose(fp);
return 1;
}
if(nextseqnum == base)
{
msec = 0;
trigger = 50; /*50 ms*/
initial = clock(); /*start the timer*/
}
nextseqnum++;
seqnum_next = nextseqnum%N;
if(seqnum_next == 0)
{
seqnum_next = N;
}
sleep(1);
}
/*There is something tricky going on with the read..
* Either there was error ,or we reached end of file.
*/
else
{
if(feof(fp))
printf("End of file\n");
if(ferror(fp))
printf("Error reading\n");
end_flag = 1; //set the flag that it has reached EOF or encountered error
break;
}
}
while(1) //wait for the acknowledgement for the sent packets till timeout , here timer value is set to 50 ms
{
difference = clock()-initial;
msec = difference*1000/CLOCKS_PER_SEC;
if(msec<trigger) //if it is not timeout then receive the ack packets
{
memset(ack_buf, 0, 65535); //clear the contents of ack_buf
memset(ack_check_len,0,1024);
memset(ack_check,0,65535);
memset(content,0,65535);
memset(temp_buf,0,65535);
//printf ("Receiving packet\n");
n = recvfrom(sock,ack_buf,1024,MSG_DONTWAIT,&server, &length); //receive the ack from the server
if(n>0)
{
j=0;
for(i=0;i<1;i++)
{
temp_buffer[j] = ack_buf[i];
j++;
}
temp_buffer[j] = '\0';
strcpy(ack_seqlen_char,temp_buffer);//get the length of the ack sequence //number
ack_seqlen = atoi(ack_seqlen_char); //converting it to int
j=0;
for(i=1;i<1+ack_seqlen;i++)
{
ack_seq_char[j]= ack_buf[i];
j++; //next bytes till i=ack_seqlen will be sequence number
}
seq_no = atoi(ack_seq_char);
printf("Ack received for the sequence number %d\n",seq_no);
j =0;
for(i=1+ack_seqlen;i<2+ack_seqlen;i++) //next byte will have the length of checksum
{
temp_buf[j] = ack_buf[i]; //extracting the checksum length
j++;
}
temp_buf[j] = '\0'; //ending the string with a null character
strcpy(ack_check_len,temp_buf); //length of checksum will be in string format
ack_checksum_len = atoi(ack_check_len); //convert it into int
j = 0;
for(i=2+ack_seqlen;i<(2+ack_seqlen+ack_checksum_len);i++) //extract the checksum
{
ack_check[j] = ack_buf[i];
j++;
}
ack_check[j] ='\0';
ack_checksum = atoi(ack_check); //the checksum will be in string format,convert it into the integer format
j=0; //extract the content i.e the actual ack message
while(i<n)
{
content[j] = ack_buf[i];
i++;
j++;
}
content[j] ='\0';
length1 = strlen(content);
actual_checksum = checksum(content,length1);//calculate the actual checksum
printf("checksum of the ack received is %d\t and the checksum of the ack sent is %d\n",actual_checksum,ack_checksum);
if(actual_checksum == ack_checksum) //if the ack is not corrupt then update the base
{
printf("successfully recived packet %d\n",seq_no);
base =seq_no+1;
if(base == nextseqnum) //go to sending next series of packets
{
printf ("base is %d\n", base);
break;
}
else
{
initial = clock(); //start timer for next in-flight packet
}
}
else //if it is a corrupt ack
{
printf("Ack corrupted,wait till timeout\n");
}
} else {
if (end_flag == 1) {
printf ("Reached END\n");
break;
}
}
}
else //if the timer is out, resend the packet from the packet with seqno
// base till nextseqnum-1,start timer
{
initial = clock();
sequence = base;
while(sequence <= nextseqnum-1)
{
n= sendto(sock,data[sequence],total_len[sequence],0,(struct sockaddr *)&server,sizeof(struct sockaddr));///send the data packet after adding the header info
if(n<0)
{
printf("error in sending message to the server");
fclose(fp);
return 1;
}
sleep(0.5);
}
}
}
if(end_flag == 1) //if there had been an error in reading file of EOF had reached break out of
// the outermost while loop
{
printf ("I am at the END\n");
break;
}
}
printf ("Sending finish packet\n");
strcpy(buff,"Finish");
n= sendto(sock,buff,1024,0,(struct sockaddr *)&server,sizeof(struct sockaddr));
if(n<0)
{
printf("error in sending message to the server");
return 1;
}
fclose(fp); //close the file to complete the transmission
t = clock()-t;
gettimeofday(&end,NULL);
double time_taken = ((double)t)/CLOCKS_PER_SEC; //in secconds
printf(" The CPU time for transmission %f seconds \n",time_taken);
double delta = ((end.tv_sec - start.tv_sec)*1000000u+ end.tv_usec - start.tv_usec)/1.e6;
printf("The actual execution time took %f seconds\n", delta);
close(sock); //close api tries to complete the transmission if there is data waiting to be transmitted
return 0;
}

I'm not sure if my netfilter is working or not

I'm trying to make a LKM netfilter that drops incoming packets if the number of packets arrived exceeds a certain limit.
There are five ports that the packets comes through, and netfiltering is done for each of those ports.
Here's part of my LKM netfilter (it uses procfs to write from user program):
#define MAX_PORT 5
static unsigned short int port[MAX_PORT];
static unsigned long limit;
static char char_limit[256];
static unsigned long data_count[MAX_PORT];
bool check_port(unsigned short int);
static unsigned int my_hook_fn( void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct iphdr *ip = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
unsigned int source, dest;
if(!skb) return NF_ACCEPT;
if(ip->protocol==IPPROTO_TCP)
{
source = htons((unsigned short int) th->source);
dest = htons((unsigned short int) th->dest);
printk(KERN_ALERT "source: %u, destination: %u\n", source, dest);
if(!check_port(source))
{
printk(KERN_ALERT "packet dropped!\n");
return NF_DROP;
}
}
return NF_ACCEPT;
}
bool check_port(unsigned short int source)
{
int i = 0;
bool found = false;
while(!found && i < MAX_PORT)
{
if(port[i] == source)
found = true;
else if(port[i] == 0)
{
port[i] = source;
found = true;
}
i++;
}
i--;
data_count[i]++;
if(data_count[i] >= limit)
{
data_count[i] = limit;
printk(KERN_ALERT "port %hu has reached the limit!\n", port[i]);
return false;
}
return true;
}
static struct nf_hook_ops my_nf_ops = {
.hook = my_hook_fn,
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST,
};
In my hook function, the NF_DROP seems to be correctly returned.
However, the result in my user space program shows that it's not.
Next is my user space program; this produces results in txt files.
void *thread_recv(void *arg);
#define MAX_CON 5
#define BUF_SIZE 200
int port[MAX_CON];
char ip[20];
int sock[MAX_CON];
void error_handling(char *msg);
void main(){
int i;
unsigned long limit;
char char_limit[256];
FILE *fp;
printf("packet limit : ");
scanf("%lu", &limit);
sprintf(char_limit, "%lu", limit);
fp = fopen("/proc/myproc/myproc", "w");
if(fp == NULL)
printf("unable to open myproc\n");
else
fprintf(fp, "%s", char_limit);
fclose(fp);
struct sockaddr_in serv_adr;
pthread_t thread_id[MAX_CON];
printf("ip :\n");
scanf("%s",ip);
printf("<port> <port> <port> <port> <port>\n");
scanf("%d %d %d %d %d", &(port[0]), &(port[1]), &(port[2]), &(port[3]), &(port[4]));
printf("%s %d\n", ip, port[0]);
for(i=0;i<5;i++){
sock[i]=socket(PF_INET, SOCK_STREAM, 0);
if(sock[i]==-1)
error_handling("socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=inet_addr(ip);
serv_adr.sin_port=htons(port[i]);
if(connect(sock[i], (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("connect() error");
else
printf("port %d connected\n", port[i]);
pthread_create(&(thread_id[i]),NULL, thread_recv,(void*)&(sock[i]));
}
while(1); // do infinitely, so user should end by their own. Ctrl + C
}
void *thread_recv(void *arg){
int clnt_sock= *(int*)arg; // get socketnumber from main
int str_len=0, i; // recv byte length
int tport=0; // portnumber matching socketnumber
char msg[BUF_SIZE];
time_t timer;
struct tm *t;
struct timespec spec;
unsigned long ms;
FILE *fp;
char filename[20]={NULL};
for(i=0;i<5;i++)
if(sock[i]==clnt_sock)
tport=port[i];
sprintf(filename,"%d.txt",tport);
fp=fopen(filename,"w+");
printf("%d port thread run\n", tport);
while((str_len=read(clnt_sock, msg, sizeof(msg)))){
msg[str_len]=NULL;
timer= time(NULL);
t= localtime(&timer);
clock_gettime(CLOCK_REALTIME, &spec);
ms = round(spec.tv_nsec / 1.0e6);
fprintf(fp,"%d:%d:%d.%lu %d %s\n",t->tm_hour,t->tm_min,t->tm_sec,ms,str_len,msg);
}
fclose(fp);
}
void error_handling(char *msg){
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
Within the thread_recv function, a txt file is created with its name as the matching port number.
What I was expecting from this was that once packet is dropped, the resulting txt file will stop being updated.
For example, if the limit is 10, then only 10 socket information will be written to the file.
But even when the ports have reached the limit, they keep updating the resulting txt files.
Does that mean that the packets have not been dropped properly?

not /n in scanf but program still waits

I've read on here that the /n in scanf makes the program wait for another input. my program however does not have a /n in scanf but it still waits for another input after i enter a number. Not sure why.
#include <stdio.h>
int main()
{
int inputNumber, index = 2, lowestPrime = 1, number = 1;
printf("Enter an integer: ");
scanf("%d", &inputNumber);
if(scanf("%d", &inputNumber) != 1)
{
printf("Invalid input");
return 1;
}
else
{
printf(" The prime factorization of %d is",inputNumber);
while(inputNumber > lowestPrime)
{
if(inputNumber % index != 0)
{
index += 1;
}
else
{
inputNumber = (inputNumber / index);
printf(" %d", index);
}
}
}
return 0;
}
You're calling scanf twice here, once for the original call and once in your if statement. Replace the statement inside the if parenthesis by
if (inputNumber!= 1)
and you should be fine!

C++ code to find BSSID OF associated network

Hello I've written the following code which is a part of a project. It is used to find the ESSID of the current associated network.
But it has a flaw: it also the displays the ESSID of the network with which I am not associated i.e. if I try to associate myself with a wireless n/w and if it is unsuccessful i.e. NO DHCP OFFERS ARE RECEIVED, then also it will display the that ESSID with which I have made my attempt.
Could anyone give me an ioctl call to find the BSSID of current associated wireless n/w?. In my opinion it is the only way with which I a can mark b/w associated and non associated.
CODE:-
int main (void)
{
int errno;
struct iwreq wreq;
CStdString result = "None";
int sockfd;
char * id;
char ESSID[100];
memset(&wreq, 0, sizeof(struct iwreq));
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
return result ;
}
CLog::Log(LOGINFO,"Socket opened successfully");
FILE* fp = fopen("/proc/net/dev", "r");
if (!fp)
{
// TBD: Error
return result;
}
char* line = NULL;
size_t linel = 0;
int n;
char* p;
int linenum = 0;
while (getdelim(&line, &linel, '\n', fp) > 0)
{
// skip first two lines
if (linenum++ < 2)
continue;
p = line;
while (isspace(*p))
++p;
n = strcspn(p, ": \t");
p[n] = 0;
strcpy(wreq.ifr_name, p);
id = new char[IW_ESSID_MAX_SIZE+100];
wreq.u.essid.pointer = id;
wreq.u.essid.length = 100;
if ( ioctl(sockfd,SIOCGIWESSID, &wreq) == -1 ) {
continue;
}
else
{
strcpy(ESSID,id);
return ESSID;
}
free(id);
}
free(line);
fclose(fp);
return result;
}