How to return to menu in Socket Client-Server - sockets

I've writen this code but it doesn't work correctly.
This is menu interface:
*************ENCODE_DECODE_BASE64**************
******* 1. Encode ********
******* 2. Decode ********
******* 3. Exit ********
***********************************************
When i choose 1, "Encode". The function runs but the process exits.
I want when I choose 1, the function to run and then after that, the menu to display again.
Can you help me?
Here is Clientcode:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024
// read filename
char *inputString(int size){
int test=0;
char *s=(char*)malloc(size);
do{
if(test!=0){
printf("File not found !!!!!!");
}
fgets(s,size,stdin);
test++;
}while(strlen(s)<=1);
return strtok(s,"\n");
}
int main(int argc, char *argv[]){
int sockfd;
struct sockaddr serverAddr; //server address
char buff[1024];
struct sockaddr_in inAddr;
long int sentBytes,revedBytes;
sockfd=socket(AF_INET,SOCK_STREAM,0); // create socket
if (sockfd == -1)
{
printf("ERROR opening socket\n");
return 1;
}
printf("Socket done\n");
inAddr.sin_family=AF_INET; //default
inAddr.sin_port=htons(5500); // service port
inet_aton("127.0.0.1",&inAddr.sin_addr);
//connectting
if(connect(sockfd,(struct sockaddr *)&inAddr,sizeof(struct sockaddr))<0){
printf("Connect failed.\n");
return 1;
}
printf("Connection accepted\n");
char *FileName; // file input
char *Result; // file return
int choice;
do{
printf("\n*************ENCODE_DECODE_BASE64**************");
printf("\n******* 1. Encode ********");
printf("\n******* 2. Decode ********");
printf("\n******* 3. Exit ********");
printf("\n***********************************************\n");
printf("Choice: ");
choice = getchar();
while(getchar() !='\n');
switch(choice)
{
case '1':
//demo encode////////////////////////////////////////
send(sockfd,"encode",5,0); // send to server when choose 1
printf("File Encode : ");
FileName = inputString(20);
FILE *fpt = fopen(FileName,"r");
if(fpt==NULL){
printf("File not found");
return -1;
}
printf("File Result: ");
Result = inputString(20);
FILE *ft = fopen(Result,"w");
while(!feof(fpt)){
if (fgets(buff,MAX,fpt) != NULL ){
sentBytes=send(sockfd,buff,1024,0);
revedBytes=recv(sockfd,buff,1024,0);
fprintf(ft,"%s\n",buff);
}
}
printf("Encode done!thanks you !\n");
//close(sockfd);
fclose(fpt);fclose(ft);
return 0;
break;
//decode ///////////////////////////////////////////////
case '2':
send(sockfd,"decode",6,0);
printf("File Decode : ");
FileName = inputString(20);
FILE *fpt1 = fopen(FileName,"r");
if(fpt1==NULL){
printf("File not found");
return -1;
}
printf("File Result : ");
Result = inputString(20);
FILE *ft1 = fopen(Result,"w");
while(!feof(fpt1)){
if (fgets(buff,MAX,fpt1) != NULL ){
sentBytes=send(sockfd,buff,1024,0);
revedBytes=recv(sockfd,buff,1024,0);
fprintf(ft1,"%s",buff);
}
}
printf("Decode done ! thanks you !\n");
//close(sockfd);
fclose(fpt1);fclose(ft1);
return 0;
break;
///////////////////////////////////////////////////////
case '3':
printf("Thanks!\n");
break;
default: printf("wrong number, please try again!\n"); break;
//end choice///////////////////////////////////////
}
}while(choice!='3');
//end menu
//close(sockfd);
//return 0;
}
and here is ServerCode:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}
void b64_decode(char *b64src, char *clrdst) {
int c, phase, i;
unsigned char in[4];
char *p;
clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break;
}
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0;
}
}
i++;
}
}
/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
}
/* encode - base64 encode a stream, adding padding if needed */
void b64_encode(char *clrstr, char *b64dst) {
unsigned char in[3];
int i, len = 0;
int j = 0;
b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++;
}
else in[i] = 0;
}
if( len ) {
encodeblock( in, b64dst, len );
}
}
}
void sig_chld(int signo) //child
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG))>0)
printf("child %d terminated\n", pid);
return;
}
int main()
{
int listen_sock, conn_sock;
int server_len, client_len,choice;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
char myb64[1024] = ""; //encode
char mydst[1024] = ""; //decode
int sentBytes,revedBytes,bytes_readi;
char buff[1024]; //buffer to send data
listen_sock = socket(AF_INET, SOCK_STREAM, 0); //create socket
if (listen_sock == -1)
{
printf("ERROR opening socket\n");
return 0;
}
printf("Socket done\n");
//Thiet lap dia chi server
server_address.sin_family = AF_INET; //default
inet_aton("127.0.0.1",&server_address.sin_addr); //ip server
server_address.sin_port = htons(5500); // port server
server_len = sizeof(server_address);
if(bind(listen_sock, (struct sockaddr *)&server_address,server_len)<0)
{
printf("ERROR on binding\n");
return 0;
}
printf("Bind done\n");
int check = listen(listen_sock,10);
if (check == -1)
{
printf("Error connect");
return 0;
}
printf("Waiting connect..\n");
while(1) {
client_len = sizeof(client_address);
conn_sock = accept(listen_sock,(struct sockaddr *)&client_address, &client_len);
if(conn_sock==-1){
printf("Error connect\n");
return 1;
}else{
printf("Accept new connection\n");
}
if(fork() == 0){
close(listen_sock);
do{
revedBytes = recv(conn_sock,buff,1024,0);
buff[revedBytes]='\0';
if(strcmp(buff,"mahoa")==0) choice=1;
else if(strcmp(buff,"giaima")==0) choice=2; else choice = 3;
switch(choice)
{
case 1:
while((revedBytes = recv(conn_sock,buff,1024,0)) > 0){
buff[revedBytes]='\0';
//printf("string send by client encode : %s\n",buff);
b64_encode(buff, myb64); //ma hoa
sentBytes=send(conn_sock,myb64,1024,0); //gui lai string da ma hoa cho client
}
close(conn_sock);//Dong ket noi cua client
exit(0);
break;
case 2:
while((revedBytes = recv(conn_sock,buff,1024,0)) > 0){
buff[revedBytes]='\0';
//printf("string send by client decode: %s\n",buff);
b64_decode(buff,mydst); // giaima
sentBytes=send(conn_sock,mydst,1024,0);
}
close(conn_sock);
exit(0);
break;
case 3:break;
}
}while(choice!=3);
break;
}
signal(SIGCHLD,sig_chld);
close(conn_sock);
}
return 1;
}

Related

ioctl in kernel module: why some commands are not executed?

I attach here my kernel module I developed and the test I am using at application level
memalloc.c
/*
* DMA memory allocation
* This kernel module allocates coherent, non-cached memory
* and returns the physical and virtual address of the allocated buffer
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include "memalloc.h"
#define DEVICE_NAME "memalloc"
// Max number of buffers
#define BUFFER_MAX_NUMBER 16
// Structure for buffer information
struct bufferInfo {
int active;
int size;
dma_addr_t handle;
int virtualAddress;
int *kernelAddress;
};
static struct bufferInfo bufferInfoTable[BUFFER_MAX_NUMBER];
// Defines which buffer is currently active - for mmap
static int activeBufferID;
struct memAllocIF {
struct device *device_p;
dev_t dev_node;
struct cdev cdev;
struct class *class_p;
};
static struct memAllocIF interface;
// Methods
static int releaseBuffer(int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
printk("Releasing buffer %d\n", i);
bufferInfoTable[i].active = 0;
dma_free_coherent(NULL, bufferInfoTable[i].size, bufferInfoTable[i].kernelAddress, bufferInfoTable[i].handle);
return 0;
}
static int reserveBuffer(size_t size)
{
int i;
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
if (bufferInfoTable[i].active == 0)
{
printk("Reserving buffer %d\n", i);
bufferInfoTable[i].active = 1;
break;
}
}
if (i < BUFFER_MAX_NUMBER)
{
bufferInfoTable[i].kernelAddress = dma_alloc_coherent(NULL, size, &bufferInfoTable[i].handle, GFP_KERNEL);
if (bufferInfoTable[i].kernelAddress == NULL)
{
printk("Allocation failure\n");
return -1;
}
bufferInfoTable[i].size = (int)size;
return i;
}
else
{
printk("No buffer available\n");
return -1;
}
}
static void cleanup(void)
{
int i;
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
if (bufferInfoTable[i].active != 0)
{
dma_free_coherent(NULL, bufferInfoTable[i].size, bufferInfoTable[i].kernelAddress, bufferInfoTable[i].handle);
bufferInfoTable[i].active = 0;
}
}
}
static unsigned int memAllocGetVirtual (int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
if (bufferInfoTable[i].active == 0)
{
printk("Inactive buffer - ID %d\n", i);
return -1;
}
printk("request for buffer %d: vaddr = %X\n", i, (unsigned int)bufferInfoTable[i].virtualAddress);
return bufferInfoTable[i].virtualAddress;
}
static unsigned int memAllocGetPhysical (int i)
{
if (i > BUFFER_MAX_NUMBER)
{
printk("Wrong bufferID %d\n", i);
return -1;
}
return (unsigned int)bufferInfoTable[i].handle;
}
static long memAllocIoctl (struct file *fd, unsigned int cmd, unsigned long arg)
{
printk("received command %u arg %lu\n", cmd, arg);
switch(cmd)
{
case MEMALLOC_RESERVE:
return reserveBuffer(arg);
break;
case MEMALLOC_RELEASE:
return releaseBuffer(arg);
break;
case MEMALLOC_GET_VIRTUAL:
return memAllocGetVirtual(arg);
break;
case MEMALLOC_GET_PHYSICAL:
return memAllocGetPhysical(arg);
break;
case MEMALLOC_ACTIVATE_BUFFER:
if (arg > BUFFER_MAX_NUMBER || bufferInfoTable[arg].active == 0)
{
printk("Wrong bufferID %lu\n", arg);
return -1;
}
activeBufferID = arg;
return arg;
break;
default:
printk("Wrong command: %d\n", cmd);
return -1;
break;
}
}
static int memAllocMmap (struct file *fd, struct vm_area_struct *vma)
{
bufferInfoTable[activeBufferID].virtualAddress = dma_common_mmap(interface.device_p, vma, bufferInfoTable[activeBufferID].kernelAddress, bufferInfoTable[activeBufferID].handle, vma->vm_end-vma->vm_start);
printk("mmap for idx %d: vaddr = %X\n", activeBufferID, (int)bufferInfoTable[activeBufferID].virtualAddress);
return bufferInfoTable[activeBufferID].virtualAddress;
}
static int memAllocRelease(struct inode *in, struct file *fd)
{
cleanup();
return 0;
}
static int memAllocOpen(struct inode *ino, struct file *file)
{
file->private_data = container_of(ino->i_cdev, struct memAllocIF, cdev);
return 0;
}
static struct file_operations fops = {
.unlocked_ioctl = memAllocIoctl,
.mmap = memAllocMmap,
.release = memAllocRelease,
.open = memAllocOpen
};
static int __init memAllocInit(void)
{
int rc;
int i;
static struct class *local_class_p = NULL;
printk("Loading DMA allocation module\n");
// Allocate a character device from the kernel for this driver
rc = alloc_chrdev_region(&interface.dev_node, 0, 1, DEVICE_NAME);
if (rc)
{
printk("Unable to get a char device number\n");
return rc;
}
// Initialize the ter device data structure before registering the character device with the kernel
cdev_init(&interface.cdev, &fops);
rc = cdev_add(&interface.cdev, interface.dev_node, 1);
if (rc)
{
printk("Unable to add char device\n");
cdev_del(&interface.cdev);
return rc;
}
// Create the device in sysfs which will allow the device node in /dev to be created
local_class_p = class_create(THIS_MODULE, DEVICE_NAME);
interface.class_p = local_class_p;
// Create the device node in /dev so the device is accessible as a character device
interface.device_p = device_create(interface.class_p, NULL, interface.dev_node, NULL, DEVICE_NAME);
if (IS_ERR(interface.device_p))
{
printk("Unable to create the device\n");
class_destroy(interface.class_p);
cdev_del(&interface.cdev);
return rc;
}
for (i = 0; i < BUFFER_MAX_NUMBER; i++)
{
bufferInfoTable[activeBufferID].active = 0;
}
return 0;
}
static void __exit my_memAllocExit(void)
{
printk("Module unloading\n");
cleanup();
cdev_del(&interface.cdev);
device_destroy(interface.class_p, interface.dev_node);
class_destroy(interface.class_p);
unregister_chrdev_region(interface.dev_node, 1);
}
module_init(memAllocInit);
module_exit(my_memAllocExit);
MODULE_AUTHOR("me");
MODULE_DESCRIPTION("Create a buffer and return physical and virtual address, for DMA userspace driver");
MODULE_LICENSE("GPL");
memalloc.h
#ifndef MEMALLOC_H
#define MEMALLOC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <linux/types.h>
#include <asm/ioctl.h>
static long memAllocIoctl (struct file *, unsigned int, unsigned long);
static int memAllocMmap (struct file *, struct vm_area_struct *);
static int memAllocRelease (struct inode *, struct file *);
static int memAllocOpen(struct inode *, struct file *);
enum memAllocCmd
{
MEMALLOC_RESERVE = 0,
MEMALLOC_RELEASE = 1,
MEMALLOC_GET_VIRTUAL = 2,
MEMALLOC_GET_PHYSICAL = 3,
MEMALLOC_ACTIVATE_BUFFER = 4,
};
#ifdef __cplusplus
}
#endif
#endif /* MEMALLOC_H */
test.c
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
// derive this from memalloc.h
enum memAllocCmd
{
MEMALLOC_RESERVE = 0,
MEMALLOC_RELEASE = 1,
MEMALLOC_GET_VIRTUAL = 2,
MEMALLOC_GET_PHYSICAL = 3,
MEMALLOC_ACTIVATE_BUFFER = 4,
};
int main ()
{
int memAllocFd;
volatile int iVaddr;
volatile int oVaddr;
volatile int iVaddr_2;
volatile int oVaddr_2;
volatile void * iPaddr;
volatile void * oPaddr;
int iBufID;
int oBufID;
int size = 2048;
memAllocFd = open("/dev/memalloc", O_RDWR);
// create iBuffer
iBufID = ioctl(memAllocFd, MEMALLOC_RESERVE, size);
iPaddr = (void *)ioctl(memAllocFd, MEMALLOC_GET_PHYSICAL, iBufID);
ioctl(memAllocFd, MEMALLOC_ACTIVATE_BUFFER, iBufID);
iVaddr = (int)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memAllocFd, 0);
ioctl(memAllocFd, MEMALLOC_GET_VIRTUAL, iBufID);
/*
if (iVaddr != iVaddr_2)
{
printf("Error: virtual addresses for buffer %d don't match: %X %X\n", iBufID, iVaddr, iVaddr_2);
}
*/
// create oBuffer
oBufID = ioctl(memAllocFd, MEMALLOC_RESERVE, size);
oPaddr = (void *)ioctl(memAllocFd, MEMALLOC_GET_PHYSICAL, oBufID);
ioctl(memAllocFd, MEMALLOC_ACTIVATE_BUFFER, oBufID);
oVaddr = (int)mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memAllocFd, 0);
ioctl(memAllocFd, MEMALLOC_GET_VIRTUAL, oBufID);
/*
if (oVaddr != oVaddr_2)
{
printf("Error: virtual addresses for buffer %d don't match: %X %X\n", oBufID, oVaddr, oVaddr_2);
}
*/
ioctl(memAllocFd, MEMALLOC_RELEASE, iBufID);
ioctl(memAllocFd, MEMALLOC_RELEASE, oBufID);
return 0;
}
Result of the test is
received command 0 arg 2048
Reserving buffer 0
received command 3 arg 0
received command 4 arg 0
mmap for idx 0: vaddr = 0
received command 0 arg 2048
Reserving buffer 1
received command 3 arg 1
received command 4 arg 1
mmap for idx 1: vaddr = 0
received command 1 arg 0
Releasing buffer 0
received command 1 arg 1
Releasing buffer 1
Which means that all ioctl calls with arg=MEMALLOC_GET_VIRTUAL are not executed, while all the others are.
What can be the reason for that?
Thanks,
Max

Can't get more than 3 active TCP connections in Mini-OS?

I'm writing an TCP server in Mini-OS(an operation system in xen), it can connect to multiple TCP clients. I wrote a simple code for handling multiple TCP clients , but there is an issue with the code. The issue is I can't get the server to connect more than three active connections. The 4th or more clients could not connect for unknown reasons. I looked around the forums and tried increasing the number limit for MEMP_NUM_TCP_PCB in opt.h (stubdom\lwip-x86_64\include\lwip\opt.h) and it didn't help either.
I'm running a TCP client on Ubuntu. Based on what I saw, the 4th client did seem connected, but an exception was thrown during the "write" function: "Resolver Error 0 (no error)"
How can I solve this problem?
//server code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MYPORT 1234 // the port users will be connecting to
#define BACKLOG 2// how many pending connections queue will hold
#define BUF_SIZE 1024
int fd_A[BACKLOG]; // accepted connection fd
int conn_amount; // current connection amount
void showclient()
{
int i;
printf("-----> client amount: %d\n", conn_amount);
for (i = 0; i < BACKLOG; i++) {
printf("BACKLOG%d ---> fd = %d\n", i, fd_A[i]);
}
printf("\n\n");
}
int main(void)
{
sleep(1);
printf("start server\n");
int sock_fd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in server_addr; // server address information
struct sockaddr_in client_addr; // connector's address information
socklen_t sin_size;
int yes = 1;
char buf[BUF_SIZE];
int ret;
int i;
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
//if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
/*if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
//perror("setsockopt");
//exit(1);
}
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK) == -1) {
printf("Set server socket nonblock failed\n");
exit(1);
}*/
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; // host byte order
server_addr.sin_port = htons(MYPORT); // short, network byte order
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // automatically fill with my IP
//memset(server_addr.sin_zero, '0', sizeof(server_addr.sin_zero));
if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind");
exit(1);
}
printf("listen...\n");
if (listen(sock_fd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
printf("listen port %d\n", MYPORT);
fd_set fdsr, wfds, efds;
int maxsock;
struct timeval tv;
conn_amount = 0;
sin_size = sizeof(client_addr);
maxsock = sock_fd;
while (1)
{
sleep(1); // it's necessary
// initialize file descriptor set
FD_ZERO(&fdsr);
FD_ZERO(&wfds);
//FD_ZERO(&efds);
FD_SET(sock_fd, &fdsr); // add fd
FD_SET(sock_fd, &wfds); // add fd
//FD_SET(sock_fd, &efds); // add fd
// timeout setting
tv.tv_sec = 30;
tv.tv_usec = 0;
// add active connection to fd set
for (i = 0; i < BACKLOG; i++) {
if (fd_A[i] != 0) {
FD_SET(fd_A[i], &fdsr);
}
}
//printf("before select!!!!!!!!!!!! ret = %d\n", ret);
if ((select(maxsock + 1, &fdsr, &wfds, (fd_set*) 0, (struct timeval*) 0)) < 0) {
perror("select");
break;
}
// check every fd in the set
for (i = 0; i < conn_amount; i++)
{
if (FD_ISSET(fd_A[i], &fdsr)) // check which fd is ready
{
ret = recv(fd_A[i], buf, sizeof(buf), 0);
if (ret <= 0)
{ // client close
printf("ret : %d and client[%d] close\n", ret, i);
close(fd_A[i]);
FD_CLR(fd_A[i], &fdsr); // delete fd
fd_A[i] = 0;
conn_amount--;
}
else
{ // receive data
if (ret < BUF_SIZE)
memset(&buf[ret], '\0', 1); // add NULL('/0')
printf("client[%d] send:%s\n", i, buf);
}
}
}
// check whether a new connection comes
if (FD_ISSET(sock_fd, &fdsr)) // accept new connection
{
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
if (new_fd <= 0)
{
perror("accept");
continue;
}
// add to fd queue
if (conn_amount < BACKLOG)
{
fd_A[conn_amount++] = new_fd;
printf("------> new connection client[%d] %s:%d\n", conn_amount,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
if (new_fd > maxsock) // update the maxsock fd for select function
maxsock = new_fd;
}
else
{
printf("max connections arrive, exit\n");
send(new_fd, "bye", 4, 0);
close(new_fd);
break;
}
}
//showclient();
}
// close other connections
for (i = 0; i < BACKLOG; i++)
{
if (fd_A[i] != 0)
{
close(fd_A[i]);
}
}
exit(0);
}
//client code
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <malloc.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define RES_LENGTH 10240
int connect_socket(char * server,int serverPort);
int send_msg(int sockfd,char * sendBuff);
char * recv_msg(int sockfd);
int close_socket(int sockfd);
int main(int argc, char ** argv)
{
int sockfd[1024] = {0};
char sendMsg[30]="zhangchengfei\r\n\r";
char* res;
int port = 1234;
char ip[128] = {0};
strncpy(ip, "10.107.19.62", 128);
if(argc > 2)
{
strncpy(ip, argv[1], 128);
port = atoi(argv[2]);
printf("Input IP: %s, port : %d\n", ip, port);
}
else if(argc > 1)
{
//port = atoi(argv[1]);
//printf("Input port : %d\n", port);
//
int num_client = atoi(argv[1]);
int i = 0;
for (i = 0; i <= num_client; i++) {
printf("start connect %d\n", i + 1);
sockfd[i]=connect_socket(ip, port);
printf("connect %d OK\n", i + 1);
getchar();
}
for (i = 0; i <= num_client; i++) {
send_msg(sockfd[i], sendMsg);
/* res=recv_msg(sockfd); */
printf("client %d send msg = %s\n", i + 1, sendMsg);
//printf(res);
//free(res);
getchar();
}
for (i = 0; i <= num_client; i++) {
close_socket(sockfd[i]);
printf("close socket %d\n", i + 1);
}
}
return 0;
}
int connect_socket(char * server,int serverPort){
int sockfd=0;
struct sockaddr_in addr;
struct hostent * phost;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
herror("Init socket error!");
return -1;
}
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(serverPort);
addr.sin_addr.s_addr = inet_addr(server);
if(addr.sin_addr.s_addr == INADDR_NONE){
phost = (struct hostent*)gethostbyname(server);
if(phost==NULL){
herror("Init socket s_addr error!");
return -1;
}
addr.sin_addr.s_addr =((struct in_addr*)phost->h_addr)->s_addr;
}
if(connect(sockfd,(struct sockaddr*)&addr, sizeof(addr))<0)
{
perror("Connect server fail!");
return -1;
}
else
return sockfd;
}
int send_msg(int sockfd,char * sendBuff)
{
int sendSize=0;
if((sendSize=send(sockfd,sendBuff,strlen(sendBuff),0))<=0){
herror("Send msg error!");
return -1;
}else
return sendSize;
}
char* recv_msg(int sockfd){
char * response;
int flag=0,recLenth=0;
response=(char *)malloc(RES_LENGTH);
memset(response,0,RES_LENGTH);
for(flag=0;;)
{
printf("======recv data:\n");
if(( recLenth=recv(sockfd,response+flag,RES_LENGTH-flag,0))==-1 )
{
free(response);
printf("Return value : %d\n", recLenth);
perror("Recv msg error : ");
return NULL;
}
else if(recLenth==0)
break;
else
{
printf("%d char recieved data : %s.\n", recLenth, response+flag);
flag+=recLenth;
recLenth=0;
}
}
printf("Return value : %d\n", recLenth);
response[flag]='0';
return response;
}
int close_socket(int sockfd)
{
close(sockfd);
return 0;
}
I have solved this problem caused by a Makefile bug in ./stubdom, after executing make crossclean , I found the .o files still existed in lwip-x86_64 folder. So I add a command find . -name "*.o" | xargs rm -f in Makefile and then anything is OK.
The reason is that lwip configure is given by the macro definition, macro definition have been replaced at the pre-compilation stage, so if I modify the lwip configure and did not delete the .o files, there is no effect. Following is the macro definitions I have modified in opt.h.
MEMP_NUM_TCP_PCB 100
MEMP_NUM_TCP_PCB_LISTEN 100
MEMP_NUM_NETCONN 100
Now the server can break through the connection limitations and more than 3 active TCP connections can be established, but sad that we have encountered another problem, the server side only can receive 61 clients of the connection requests. If exceeding the clients number, server side error will be reported as follows:
ASSERTION FAILED: mbox->reader != mbox->writer at lwip-arch.c:124.
Do_exit called!
base is 0x29fe78 caller is 0x4d49d
base is 0x29fe98 caller is 0x5a05a
base is 0x29fec8 caller is 0x5a153
base is 0x29fef8 caller is 0x634a1
base is 0x29ff28 caller is 0x65074
base is 0x29ff78 caller is 0x5d0dd
base is 0x29ffc8 caller is 0x59822
base is 0x29ffe8 caller is 0x33da
How can I solve the above problem?

Is there a connection limitation using LWIP?

I'm writing a TCP server using Lwip Protocol, normally the server can connect to multiple TCP clients. However I have a problem , the server can't connect more than three active connections. The 4th or more clients could not connect for unknown reasons. I looked around the forums and tried increasing the number limit for MEMP_NUM_TCP_PCB in opt.h (lwip-x86_64\include\lwip\opt.h) but it didn't help.
Following is my code, and my questions is whether is there a max connection limitation using LWIP ? Maximum number of connections is 3 or more?
//server code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MYPORT 1234 // the port users will be connecting to
#define BACKLOG 2// how many pending connections queue will hold
#define BUF_SIZE 1024
int fd_A[BACKLOG]; // accepted connection fd
int conn_amount; // current connection amount
void showclient()
{
int i;
printf("-----> client amount: %d\n", conn_amount);
for (i = 0; i < BACKLOG; i++) {
printf("BACKLOG%d ---> fd = %d\n", i, fd_A[i]);
}
printf("\n\n");
}
int main(void)
{
sleep(1);
printf("start server\n");
int sock_fd, new_fd; // listen on sock_fd, new connection on new_fd
struct sockaddr_in server_addr; // server address information
struct sockaddr_in client_addr; // connector's address information
socklen_t sin_size;
int yes = 1;
char buf[BUF_SIZE];
int ret;
int i;
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
//if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
/*if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
//perror("setsockopt");
//exit(1);
}
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK) == -1) {
printf("Set server socket nonblock failed\n");
exit(1);
}*/
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; // host byte order
server_addr.sin_port = htons(MYPORT); // short, network byte order
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // automatically fill with my IP
//memset(server_addr.sin_zero, '0', sizeof(server_addr.sin_zero));
if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind");
exit(1);
}
printf("listen...\n");
if (listen(sock_fd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
printf("listen port %d\n", MYPORT);
fd_set fdsr, wfds, efds;
int maxsock;
struct timeval tv;
conn_amount = 0;
sin_size = sizeof(client_addr);
maxsock = sock_fd;
while (1)
{
sleep(1); // it's necessary
// initialize file descriptor set
FD_ZERO(&fdsr);
FD_ZERO(&wfds);
//FD_ZERO(&efds);
FD_SET(sock_fd, &fdsr); // add fd
FD_SET(sock_fd, &wfds); // add fd
//FD_SET(sock_fd, &efds); // add fd
// timeout setting
tv.tv_sec = 30;
tv.tv_usec = 0;
// add active connection to fd set
for (i = 0; i < BACKLOG; i++) {
if (fd_A[i] != 0) {
FD_SET(fd_A[i], &fdsr);
}
}
//printf("before select!!!!!!!!!!!! ret = %d\n", ret);
if ((select(maxsock + 1, &fdsr, &wfds, (fd_set*) 0, (struct timeval*) 0)) < 0) {
perror("select");
break;
}
// check every fd in the set
for (i = 0; i < conn_amount; i++)
{
if (FD_ISSET(fd_A[i], &fdsr)) // check which fd is ready
{
ret = recv(fd_A[i], buf, sizeof(buf), 0);
if (ret <= 0)
{ // client close
printf("ret : %d and client[%d] close\n", ret, i);
close(fd_A[i]);
FD_CLR(fd_A[i], &fdsr); // delete fd
fd_A[i] = 0;
conn_amount--;
}
else
{ // receive data
if (ret < BUF_SIZE)
memset(&buf[ret], '\0', 1); // add NULL('/0')
printf("client[%d] send:%s\n", i, buf);
}
}
}
// check whether a new connection comes
if (FD_ISSET(sock_fd, &fdsr)) // accept new connection
{
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
if (new_fd <= 0)
{
perror("accept");
continue;
}
// add to fd queue
if (conn_amount < BACKLOG)
{
fd_A[conn_amount++] = new_fd;
printf("------> new connection client[%d] %s:%d\n", conn_amount,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
if (new_fd > maxsock) // update the maxsock fd for select function
maxsock = new_fd;
}
else
{
printf("max connections arrive, exit\n");
send(new_fd, "bye", 4, 0);
close(new_fd);
break;
}
}
//showclient();
}
// close other connections
for (i = 0; i < BACKLOG; i++)
{
if (fd_A[i] != 0)
{
close(fd_A[i]);
}
}
exit(0);
}
//client code
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <malloc.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define RES_LENGTH 10240
int connect_socket(char * server,int serverPort);
int send_msg(int sockfd,char * sendBuff);
char * recv_msg(int sockfd);
int close_socket(int sockfd);
int main(int argc, char ** argv)
{
int sockfd[1024] = {0};
char sendMsg[30]="zhangchengfei\r\n\r";
char* res;
int port = 1234;
char ip[128] = {0};
strncpy(ip, "10.107.19.62", 128);
if(argc > 2)
{
strncpy(ip, argv[1], 128);
port = atoi(argv[2]);
printf("Input IP: %s, port : %d\n", ip, port);
}
else if(argc > 1)
{
//port = atoi(argv[1]);
//printf("Input port : %d\n", port);
//
int num_client = atoi(argv[1]);
int i = 0;
for (i = 0; i <= num_client; i++) {
printf("start connect %d\n", i + 1);
sockfd[i]=connect_socket(ip, port);
printf("connect %d OK\n", i + 1);
getchar();
}
for (i = 0; i <= num_client; i++) {
send_msg(sockfd[i], sendMsg);
/* res=recv_msg(sockfd); */
printf("client %d send msg = %s\n", i + 1, sendMsg);
//printf(res);
//free(res);
getchar();
}
for (i = 0; i <= num_client; i++) {
close_socket(sockfd[i]);
printf("close socket %d\n", i + 1);
}
}
return 0;
}
int connect_socket(char * server,int serverPort){
int sockfd=0;
struct sockaddr_in addr;
struct hostent * phost;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
herror("Init socket error!");
return -1;
}
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(serverPort);
addr.sin_addr.s_addr = inet_addr(server);
if(addr.sin_addr.s_addr == INADDR_NONE){
phost = (struct hostent*)gethostbyname(server);
if(phost==NULL){
herror("Init socket s_addr error!");
return -1;
}
addr.sin_addr.s_addr =((struct in_addr*)phost->h_addr)->s_addr;
}
if(connect(sockfd,(struct sockaddr*)&addr, sizeof(addr))<0)
{
perror("Connect server fail!");
return -1;
}
else
return sockfd;
}
int send_msg(int sockfd,char * sendBuff)
{
int sendSize=0;
if((sendSize=send(sockfd,sendBuff,strlen(sendBuff),0))<=0){
herror("Send msg error!");
return -1;
}else
return sendSize;
}
char* recv_msg(int sockfd){
char * response;
int flag=0,recLenth=0;
response=(char *)malloc(RES_LENGTH);
memset(response,0,RES_LENGTH);
for(flag=0;;)
{
printf("======recv data:\n");
if(( recLenth=recv(sockfd,response+flag,RES_LENGTH-flag,0))==-1 )
{
free(response);
printf("Return value : %d\n", recLenth);
perror("Recv msg error : ");
return NULL;
}
else if(recLenth==0)
break;
else
{
printf("%d char recieved data : %s.\n", recLenth, response+flag);
flag+=recLenth;
recLenth=0;
}
}
printf("Return value : %d\n", recLenth);
response[flag]='0';
return response;
}
int close_socket(int sockfd)
{
close(sockfd);
return 0;
}
I have solved this problem caused by a Makefile bug in ./stubdom, after executing make crossclean , I found the .o files still existed in lwip-x86_64 folder. So I add a command find . -name "*.o" | xargs rm -f in Makefile and then anything is OK.
The reason is that lwip configure is given by the macro definition, macro definition have been replaced at the pre-compilation stage, so if I modify the lwip configure and did not delete the .o files, there is no effect. Following is the macro definitions I have modified in opt.h.
MEMP_NUM_TCP_PCB 100
MEMP_NUM_TCP_PCB_LISTEN 100
MEMP_NUM_NETCONN 100
Now the server can break through the connection limitations and more than 3 active TCP connections can be established.

how to write v4L capturing program for usb web cam (640x480)

i installed the usb webcam driver in linux 2.6 version
then i want to capture using V4L please any one reply me how can i write the program to capture using webcam
I work with V4l using the reference of the linuxTV (http://linuxtv.org/downloads/v4l-dvb-apis/). They have the documentation about V4l and some examples. Take a look at the following example (i got from the linuxTV):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include "../libv4l/include/libv4l2.h"
#define CLEAR(x) memset(&(x), 0, sizeof(x))
struct buffer {
void *start;
size_t length;
};
static void xioctl(int fh, int request, void *arg)
{
int r;
do {
r = v4l2_ioctl(fh, request, arg);
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
if (r == -1) {
fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
int main(int argc, char **argv)
{
struct v4l2_format fmt;
struct v4l2_buffer buf;
struct v4l2_requestbuffers req;
enum v4l2_buf_type type;
fd_set fds;
struct timeval tv;
int r, fd = -1;
unsigned int i, n_buffers;
char *dev_name = "/dev/video0";
char out_name[256];
FILE *fout;
struct buffer *buffers;
fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (fd < 0) {
perror("Cannot open device");
exit(EXIT_FAILURE);
}
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
printf("Libv4l didn't accept RGB24 format. Can't proceed.\n");
exit(EXIT_FAILURE);
}
if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
printf("Warning: driver is sending image at %dx%d\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
CLEAR(req);
req.count = 2;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS, &req);
buffers = calloc(req.count, sizeof(*buffers));
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
xioctl(fd, VIDIOC_QUERYBUF, &buf);
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
perror("mmap");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < n_buffers; ++i) {
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);
for (i = 0; i < 20; i++) {
do {
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
r = select(fd + 1, &fds, NULL, NULL, &tv);
} while ((r == -1 && (errno = EINTR)));
if (r == -1) {
perror("select");
return errno;
}
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_DQBUF, &buf);
sprintf(out_name, "out%03d.ppm", i);
fout = fopen(out_name, "w");
if (!fout) {
perror("Cannot open image");
exit(EXIT_FAILURE);
}
fprintf(fout, "P6\n%d %d 255\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
fclose(fout);
xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMOFF, &type);
for (i = 0; i < n_buffers; ++i)
v4l2_munmap(buffers[i].start, buffers[i].length);
v4l2_close(fd);
return 0;
}

Raw sockets communication over Wifi - receiver not able to receive packets

I am trying to use raw sockets to send packets from a transmitter to the receiver . The code works fine when i deploy both the transmitter and the receiver on my Mac or my friends Dell(Ubuntu 12.04 installed on both). I run the transmitter and receiver in two different terminal windows and it works fine.
But when i run the transmitter on one machine and the receiver on the other , the receiver does not receive any packets. Could someone point out the problem? I am very new to socket programming and therefore please forgive any stupid mistakes.
Transmitter :
/* Function to send a packet using sendto */
int SendPacket(int sockaddress,struct packet *mypacket, int packet_len)
{
int sent= 0;
if((sent = write(sockaddress, mypacket, packet_len)) != packet_len)
{ return 0; }
else
{ return 1; }
}
/* Function to create the raw socket for the monitor interface and also bind the socket to
the interface */
int create_raw_socket(char *dev)
{
struct sockaddr_ll sll;
struct ifreq ifr;
int fd, ifi, rb;
bzero(&sll, sizeof(sll));
bzero(&ifr, sizeof(ifr));
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
assert(fd != -1);
strncpy((char *)ifr.ifr_name, dev, IFNAMSIZ);
ifi = ioctl(fd, SIOCGIFINDEX, &ifr);
assert(ifi != -1);
sll.sll_protocol = htons(ETH_P_ALL);
sll.sll_family = PF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_pkttype = PACKET_OTHERHOST;
rb = bind(fd, (struct sockaddr *)&sll,sizeof(sll));
assert(rb != -1);
return fd;
}
/* Main function */
int main(int argc, char**argv)
{
int x,fd,s;
int sockaddress,len;
char dest_packet[PACKET_LENGTH];
int count= atoi(argv[2]);
char ch;
struct packet mypacket;
struct ieee80211_radiotap_header ratap_header;
struct ieee80211_hdr_3addr iee802_header;
unsigned char addr1[ETH_ALEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char addr2[ETH_ALEN] = {0x13,0x22,0x33,0x44,0x55,0x66};
unsigned char addr3[ETH_ALEN] = {0x13,0x22,0x33,0x44,0x55,0x66};
/* Radio tap header data */
ratap_header.it_version = 0x00;
ratap_header.it_pad = 0x00;
ratap_header.it_len = 0x06;
ratap_header.it_pad2 = 0x00;
ratap_header.it_present = 0x8000;
mypacket.rtap_header = ratap_header;
/* ieee80211 header data */
iee802_header.frame_ctl = 0x0801;
iee802_header.duration_id = 0x0000;
strcpy(iee802_header.addr1,addr1);
strcpy(iee802_header.addr2,addr2);
strcpy(iee802_header.addr3,addr3);
iee802_header.seq_ctl = 0x1086;
mypacket.iee802_header=iee802_header;
/* Payload */
unsigned char payload[PACKET_LENGTH]="test";
unsigned char stop_injection[5]="stop";
strcpy(mypacket.payload , payload);
len = sizeof(mypacket) ;
/* Sending the packet over the interface */
printf("\n Press Y to start packet injection \n");
while((ch = getchar()) != 'Y');
while((count--) > 0)
{
sockaddress = create_raw_socket(argv[1]);
if(!SendPacket(sockaddress, &mypacket, len))
perror("Error sending packet");
else
{
printf("Packet sent successfully with payload : %s\n" , mypacket.payload);
printf("\n size of the packet being send is %d \n " , len);
}
}
/* Packet to indicate the end of reception */
strcpy(mypacket.payload , stop_injection);
len = sizeof(mypacket) ;
int temp=SendPacket(sockaddress , &mypacket , len);
close(sockaddress);
printf("\n End of packet transmission ........................ \n");
return 0;
}
Receiver :
int main(int argc, char **argv)
{
struct sockaddr addr;
int sock_fd, fromlen,s;
char buf[PACKET_LENGTH];
char *dev = argv[1];
struct packet mypacket;
struct packet *ptr;
int recv_count=0;
sock_fd = create_raw_socket(dev); /* Creating the raw socket */
printf("\n Waiting to receive packets ........ \n");
while(1)
{
fromlen=sizeof(addr);
int x= recvfrom(sock_fd,&mypacket,sizeof(struct packet),0,&addr,&fromlen);
struct sockaddr_ll* temp;
temp = (struct sockaddr_ll*)(&addr);
if(temp->sll_pkttype == 4)
{
recv_count++;
if(strcmp(mypacket.payload , "stop") == 0)
break;
/* Payload received */
printf("\nPayload Received from client : %s \n ", mypacket.payload);
}
}
close(sock_fd);
return 0;
Data structures :
struct ieee80211_radiotap_header {
unsigned char it_version;
unsigned char it_pad;
uint16_t it_len;
uint16_t it_pad2;
uint32_t it_present;
};
/* Structure for 80211 header */
struct ieee80211_hdr_3addr {
uint16_t frame_ctl;
uint16_t duration_id;
unsigned char addr1[ETH_ALEN];
unsigned char addr2[ETH_ALEN];
unsigned char addr3[ETH_ALEN];
uint16_t seq_ctl;
} __attribute__ ((packed));
/* Structure of the packet containing the radiotap header, ieee802.11 header and payload
*/
struct packet {
struct ieee80211_radiotap_header rtap_header;
struct ieee80211_hdr_3addr iee802_header;
unsigned char payload[30];
};
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/sockios.h>
#include <net/ethernet.h> /* the L2 protocols */
#include <linux/if.h>
#include <linux/if_arp.h>
#include <arpa/inet.h>
#define NIC_NAME "wlan0"
/*our MAC address*/
static uint8_t gu8a_src_mac[6] = {0x11, 0x22, 0x33, 0x44 0x55, 0x66};
/*other host MAC address*/
static uint8_t gu8a_dest_mac[6] = {0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC};
int32_t get_nic_index (uint8_t *pu8_nic_card_name);
void* sock_recv_thread (void *p_arg);
int
main (void)
{
struct sockaddr_ll s_dest_addr;
int32_t s32_sock = -1;
int32_t s32_res = -1;
pthread_t ul_recv_thd_id = -1;
uint16_t u16_data_off = 0;
uint16_t u16_i = 0;
uint8_t *pu8a_frame = NULL;
uint8_t *pu8a_data = NULL;
printf ("Socket raw test\n");
(void) memset (&s_dest_addr, 0, sizeof (s_dest_addr));
pu8a_frame = (uint8_t *) calloc (ETH_FRAME_LEN, 1);
if( NULL == pu8a_frame )
{
printf ("Could not get memory for the transmit frame\n");
goto LABEL_CLEAN_EXIT;
}
u16_data_off = (uint16_t) (ETH_FRAME_LEN - ETH_DATA_LEN);
pu8a_data = pu8a_frame + u16_data_off;
s32_sock = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
if( -1 == s32_sock )
{
perror ("Could not create the socket");
goto LABEL_CLEAN_EXIT;
}
printf ("Socket created\n");
fflush (stdout);
(void) pthread_create (&ul_recv_thd_id, NULL, sock_recv_thread, &s32_sock);
sleep (1);
s_dest_addr.sll_family = AF_PACKET;
/*we don't use a protocol above ethernet layer, just use anything here*/
s_dest_addr.sll_protocol = htons(ETH_P_ALL);
s_dest_addr.sll_ifindex = get_nic_index ((uint8_t *) NIC_NAME);
s_dest_addr.sll_hatype = ARPHRD_ETHER;
s_dest_addr.sll_pkttype = PACKET_OTHERHOST; //PACKET_OUTGOING
s_dest_addr.sll_halen = ETH_ALEN;
/*MAC - begin*/
s_dest_addr.sll_addr[0] = gu8a_dest_mac[0];
s_dest_addr.sll_addr[1] = gu8a_dest_mac[1];
s_dest_addr.sll_addr[2] = gu8a_dest_mac[2];
s_dest_addr.sll_addr[3] = gu8a_dest_mac[3];
s_dest_addr.sll_addr[4] = gu8a_dest_mac[4];
s_dest_addr.sll_addr[5] = gu8a_dest_mac[5];
/*MAC - end*/
s_dest_addr.sll_addr[6] = 0x00;/*not used*/
s_dest_addr.sll_addr[7] = 0x00;/*not used*/
/*set the frame header*/
(void) memcpy (pu8a_frame, gu8a_dest_mac, ETH_ALEN);
(void) memcpy (pu8a_frame+ETH_ALEN , gu8a_src_mac, ETH_ALEN);
printf ("******Sending data using raw socket over '" NIC_NAME "'\n");
while( 1 )
{
(void) memset (&pu8a_data[u16_data_off], '\0', ETH_DATA_LEN);
(void) snprintf ((char *) &pu8a_data[u16_data_off],
ETH_DATA_LEN,
"Raw packet test, %d",
u16_i++);
s32_res = sendto (s32_sock,
pu8a_frame,
ETH_FRAME_LEN,
0,
(struct sockaddr*)&s_dest_addr,
sizeof(s_dest_addr));
if( -1 == s32_res )
{
perror ("Socket send failed");
goto LABEL_CLEAN_EXIT;
}
sleep (1);
}
/*printf ("Waiting for receive thread to exit\n");
pthread_join (ul_recv_thd_id, NULL);*/
LABEL_CLEAN_EXIT:
if( s32_sock > 0 )
{
close (s32_sock);
}
printf ("***** Raw Socket test- end\n");
return EXIT_SUCCESS;
}
void*
sock_recv_thread (void *p_arg)
{
struct sockaddr_ll s_src_addr;
int32_t s32_sock = * ((int32_t *)p_arg);
int32_t s32_res = -1;
uint16_t u16_data_off = 0;
uint8_t *pu8a_frame = NULL;
printf ("Socket receive thread\n");
u16_data_off = (uint16_t) (ETH_FRAME_LEN - ETH_DATA_LEN);
pu8a_frame = (uint8_t*) calloc (ETH_FRAME_LEN, 1);
if( NULL == pu8a_frame )
{
printf ("Could not get memory for the receive frame\n");
goto LABEL_CLEAN_EXIT;
}
(void) memset (&s_src_addr, 0, sizeof (s_src_addr));
s_src_addr.sll_family = AF_PACKET;
/*we don't use a protocol above ethernet layer, just use anything here*/
s_src_addr.sll_protocol = htons(ETH_P_ALL);
s_src_addr.sll_ifindex = get_nic_index ((uint8_t *) NIC_NAME);
s_src_addr.sll_hatype = ARPHRD_ETHER;
s_src_addr.sll_pkttype = PACKET_HOST;//PACKET_OTHERHOST;
s_src_addr.sll_halen = ETH_ALEN;
s32_res = bind (s32_sock,
(struct sockaddr *) &s_src_addr,
sizeof(s_src_addr));
if( -1 == s32_res )
{
perror ("Could not bind to the socket");
goto LABEL_CLEAN_EXIT;
}
printf ("Socket bind successful\n");
while( 1 )
{
struct sockaddr_ll s_sender_addr;
socklen_t u32_sender_addr_len = sizeof (s_sender_addr);
(void) memset (&s_sender_addr, 0, sizeof (s_sender_addr));
s32_res = recvfrom (s32_sock,
pu8a_frame,
ETH_FRAME_LEN,
0,
(struct sockaddr *) &s_sender_addr,
&u32_sender_addr_len);
if( -1 == s32_res )
{
perror ("Socket receive failed");
break;
}
else if( s32_res < 0 )
{
perror ("Socket receive, error ");
}
else
{
uint16_t u16_i = 0;
printf ("Received data from ");
for( u16_i=0; u16_i<sizeof(s_sender_addr.sll_addr)-2; u16_i++ )
{
printf ("%02x:", s_sender_addr.sll_addr[u16_i]);
}
printf ("\t");
printf ("Received data %s\n\n", &pu8a_frame[u16_data_off]);
}
}
LABEL_CLEAN_EXIT:
return (NULL);
}
int32_t
get_nic_index (uint8_t *pu8_nic_card_name)
{
int32_t s32_sock_fd = -1;
int32_t s32_res = -1;
struct ifreq s_ifr;
(void) memset (&s_ifr, 0, sizeof (s_ifr));
s32_sock_fd = socket (AF_INET, SOCK_DGRAM, 0);
if( -1 == s32_sock_fd )
{
perror ("get_nic_index(): socket failed");
goto LABEL_CLEAN_EXIT;
}
s_ifr.ifr_addr.sa_family = AF_INET;
strncpy(s_ifr.ifr_name, (char *) pu8_nic_card_name, IFNAMSIZ);
s32_res = ioctl(s32_sock_fd, SIOCGIFINDEX, &s_ifr);
if( -1 == s32_res )
{
perror ("get_nic_index(): ioctl failed");
}
close (s32_sock_fd);
LABEL_CLEAN_EXIT:
return (s_ifr.ifr_ifru.ifru_ivalue);
}