Use libpcap and sockets to transmit a packet whenever you receive - c

I am trying to make a program, so that whenever I receive a packet in an interface from a specific MAC address I want to transmit another packet (the reply packets contained in a pcap file). The program below partially works.It has two problems.
There is no way to achieve synchronization, i.e. transmit whenever I receive.
Additionally, for some unknown reason,despite the replay pcap file that I want to use as a response to every packet that I receive,contains 65000 packets, only 800 are transmitted (unsynchronized again) and the program terminates with no errors...
Any thoughts? Thank you!
#include <time.h>
#include <pcap.h>
#include <libnet.h>
#include <signal.h>
#include <sys/wait.h>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>
#include <netinet/if_ether.h>
int make_raw_sock(const char *interface, struct sockaddr_ll *sa);
int main(int argc, char *argv[])
{
const char *srcmac;
char mac[]={0x28,0x63,0x36,0x91,0x3c,0x0e};
//SET UP FOR INJECTING SOCKET
//Buffer to send data.
char buf[1514];
struct sockaddr_ll sa;
const u_char *packetstored;
const u_char *packetrx;
struct pcap_pkthdr headerst;
struct pcap_pkthdr headerrx;
pcap_t *mypcapfile;
pcap_t *p;
//Create the socket for injection.
int ps = 0;
ps = make_raw_sock("lo", &sa);
if (ps<0)
{
fprintf(stderr,"Failure in socket creation\n");
exit(-1);
}
//PARAMETERS FOR LIBPCAP
//The maximum number of packets to be captured.
//uint32_t count = 250000;
//The snapshot lenght.
uint32_t snaplen = 1514;
//Buffer for errors.
char errbuf[PCAP_ERRBUF_SIZE];
//Set interface in promiscuous mode.
int promisc = 1;
//timeout, in milliseconds.
int to_ms = 1000;
fprintf(stdout,"Parent process id = %d\n",getpid());
if (!(p = pcap_open_live("lo", snaplen, promisc, to_ms, errbuf)))
{
fprintf(stderr, "Error opening interface %s: %s\n","lo", errbuf);
exit(EXIT_FAILURE);
}
mypcapfile = pcap_open_offline("replay3.pcap", errbuf);
if (mypcapfile == NULL)
{
printf("Error pcap_open_offline(): %s\n", errbuf);
exit(EXIT_FAILURE);
}
int counter;
while (1)
{
packetrx = pcap_next(p, &headerrx);
srcmac = packetrx;
if (packetrx == NULL)
{
break;
}
else
{
if (!strncmp(srcmac,mac,6))
{
packetstored = pcap_next(mypcapfile, &headerst);
memcpy(buf,packetstored,headerst.caplen);
sendto(ps, buf, headerst.caplen, 0, (struct sockaddr*)&sa, sizeof(sa));
counter = counter + 1;
}
}
}
fprintf(stdout,"Packets sent:%d\n",counter);
return (0);
}
int make_raw_sock(const char *interface, struct sockaddr_ll *sa)
{
int ps;
struct ifreq ifr;
ps = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (ps < 0)
{
return ps;
}
strcpy(ifr.ifr_name, interface);
if (ioctl(ps, SIOCGIFINDEX, &ifr) != 0)
{
close(ps);
return -1;
}
memset(sa, 0, sizeof(*sa));
sa->sll_family = AF_PACKET;
sa->sll_ifindex = ifr.ifr_ifindex;
sa->sll_halen = sizeof(struct ether_addr);
return ps;
}

Related

SocketCAN how to send messages as soon as possible without data loss

I want to measure the maximum speed at which I can send messages via SocketCan from one Raspberry Pi (sender) using PiCan2 to another Raspberry Pi (recipient). The sender reads a 20KiB file, then each byte is sent separately via CAN. The recipient reads the message and saves it on their side to a file. Then I compare if both files are the same.
Initially, I used sleep () and typed the delay from sending each frame.
Then I sent a message and waited for a reply in the form of an empty frame, after which I sent another message.
Now I wanted to use the msg_flags flag and read MSG_CONFIRM to check if the message was delivered, but it doesn't work properly.
How can I read the MSG_CONFIRM flag? Is there another way to send messages as quickly as possible without taking up all of the buffer space and without losing some of the messages?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <unistd.h>
main(void)
{
int i = 0;
int recv_own_msgs = 1;
int flags =0;
int s;
struct msghdr msg;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
char ch;
FILE *fpbr;
ssize_t len;
const char *ifname = "can0";
// *************** read file to send
fpbr = fopen("/home/pi/Desktop/file_to_send.txt", "rb");
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) == -1)
{
perror("Error while opening socket");
return -1;
}
// *******************enable retransmission
setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs, sizeof(recv_own_msgs));
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
perror("Error in socket bind");
return -2;
}
msg.msg_flags = 0;
while(1)
{
++i;
// read from file to variable
ch = fgetc(fpbr);
frame.can_id = i;
frame.can_dlc = 1;
frame.data[0] = ch;
//send message
write(s, &frame, sizeof(struct can_frame));
//Here I would like to receive msg_flags after each message is sent and read and use MSG_CONFIRM
// to check if the message was correctly received by the other device to be able to send another message
len = recvmsg(s, &msg, flags);
if (msg.msg_flags==MSG_CONFIRM) // msg_flags is 0, not MSG_CONFIRM
{
printf("yes");
}
if (i > 1000)
{
break;
}
}
fclose(fpbr);
return 0;
}

I am unable to print message recived from client side in c server using socket?

In debugging I can see that values of rx_buffer changes to what is send from client but printf function and even fputs function is not printng the value on terminal or updating the output file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
// Constants defined
#define SERVER_PORT 3333
#define RX_BUFFER_SIZE 1024
#define TX_BUFFER_SIZE 1024
#define MAXCHAR 1000 // max characters to read from txt file
// Global variables
struct sockaddr_in dest_addr;
struct sockaddr_in source_addr;
char rx_buffer[RX_BUFFER_SIZE]; // buffer to store data from client
char tx_buffer[RX_BUFFER_SIZE]; // buffer to store data to be sent to client
char ipv4_addr_str[128]; // buffer to store IPv4 addresses as string
char ipv4_addr_str_client[128]; // buffer to store IPv4 addresses as string
int listen_sock;
char line_data[MAXCHAR];
FILE *input_fp, *output_fp;
int socket_create(struct sockaddr_in dest_addr, struct sockaddr_in source_addr){
int addr_family;
int ip_protocol;
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(SERVER_PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
int sock,p;
printf("Create the socket\n");
sock=socket(addr_family , SOCK_STREAM , 0);
if((bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)))<0){
perror("Bind failed.");
}
else{
printf("bind done");
}
char client[100];
listen(sock,1);
printf("Waiting for incoming connections...\n");
p = accept(sock, (struct sockaddr *)&source_addr, (socklen_t*)&source_addr);
if(p<0){ perror("accept failed");} printf("Client Address=%s\n",inet_ntop(AF_INET,&source_addr.sin_addr,client,sizeof(client)));
return p;
}
int receive_from_send_to_client(int sock){
char mess[10]="hello";
int len;
len=recv(sock , rx_buffer, sizeof(rx_buffer),0);
send(sock , mess , 5,0);
return 0;
}
int main() {
char *output_file_name = "data_from_client.txt";
// Create socket and accept connection from client
int sock = socket_create(dest_addr, source_addr);
output_fp = fopen(output_file_name, "w");
if (output_fp == NULL){
printf("Could not open file %s\n",output_file_name);
return 1;
}
while (1) {
receive_from_send_to_client(sock);
printf("%s",rx_buffer);
fputs(rx_buffer, output_fp);
fputs("\n", output_fp);
}
return 0;
}
In debugging I can see that values of rx_buffer are changing but not able to put that in file or print the message.
Note:- I am sending message from a python client.
in while ,you should open your file always and after putting data into the file close file descriptor properly.
see this code in main(),
int main() {
char *output_file_name = "data_from_client.txt";
// Create socket and accept connection from client
int sock = socket_create(dest_addr, source_addr);
while (1) {
output_fp = fopen(output_file_name, "a+");
if (output_fp == NULL){
printf("Could not open file %s\n",output_file_name);
return 1;
}
receive_from_send_to_client(sock);
printf("%s",rx_buffer);
fprintf(output_fp,"%s",rx_buffer);
fclose(output_fp);
}
return 0;
}

Sending netfilter hook message to user space module via netlink socket success but loop

I am a beginner in Android kernel space programming. In my modules, kernel and user space module are successfully communicating via netlink sockets and netfilter hook also works. But when I send netfilter message to user space module via netlink socket, it has a big bug! Netlink transmits message via socket, but the netfilter hook the transmission again, so it has a loop and never ends! How can I solve the problem or how to just ignore the netlink sockets and hook the other network socket? The kernel version is android-goldfish 3.4.(My English is not good, hope it clear to understand. Thanks!)
the kernel module:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/unistd.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#define MY_GROUP 1
#define MAX_SIZE 1024
struct task_struct *mythread = NULL;
struct sock *nl_sk = NULL;
static void nl_receive_callback (struct sk_buff *skb)
{
nlmsg_free(skb);
}
static void kernel_send_nl_msg(const char *msg)
{
struct nlmsghdr *nlsk_mh;
struct sk_buff *socket_buff;
socket_buff = nlmsg_new(MAX_SIZE, GFP_KERNEL);
nlsk_mh = nlmsg_put(socket_buff, 0, 0, NLMSG_DONE, MAX_SIZE, 0);
NETLINK_CB(socket_buff).pid = 0;
NETLINK_CB(socket_buff).dst_group = MY_GROUP;
strcpy(nlmsg_data(nlsk_mh), msg);
nlmsg_multicast(nl_sk, socket_buff, 0, MY_GROUP, GFP_KERNEL);
return;
}
unsigned int nfhook(
unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
char inetmsg[128] = {0};
__be32 sip, dip;
if (skb)
{
iph = ip_hdr(skb);
sip = iph->saddr;
dip = iph->daddr;
snprintf(inetmsg, 128,
"{'netObject':[{'saddr':'%d.%d.%d.%d:%u', 'daddr':'%d.%d.%d.%d:%u', 'protocol':'%x'}]}\n",
NIPQUAD(sip), NIPQUAD(dip), iph->protocol);
kernel_send_nl_msg(strim(inetmsg));
printk("%s\n", inetmsg);
}
return NF_ACCEPT;
}
struct nf_hook_ops out_nfho = {
.list = {NULL, NULL},
.hook = nfhook,
.hooknum = NF_INET_POST_ROUTING,
.pf = PF_INET,
.priority = NF_IP_PRI_FIRST,
};
int init_module(void)
{
nl_sk = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, nl_receive_callback, NULL, THIS_MODULE);
if(!nl_sk)
{
printk(KERN_ERR "my_net_link: create netlink socket error.\n");
return 1;
}
mythread = kthread_run(kernel_send_nl_msg, "init", "network-monitor");
printk("Module Ready!");
nf_register_hook(&out_nfho);
return 0;
}
void cleanup_module(void)
{
if(nl_sk != NULL)
{
sock_release(nl_sk->sk_socket);
}
nf_unregister_hook(&out_nfho);
printk("Remove Module!");
}
Userspace program:
#include <sys/socket.h>
#include <linux/netlink.h>
#include <stdio.h>
#include <errno.h>
#include <cutils/log.h>
#define MY_GROUP 1
#define MAX_SIZE 1024
#define LOG_TAG "APP LOG TAG"
int main(int argc, char* argv[])
{
int sock_fd, retval;
struct sockaddr_nl user_sockaddr;
struct nlmsghdr *nl_msghdr;
struct msghdr msghdr;
struct iovec iov;
char kernel_msg[256] = {0};
sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
if (sock_fd == -1)
{
sprintf(kernel_msg, "error getting socket: %s", strerror(errno));
LOGV(strerror(kernel_msg));
printf("error getting socket: %s", strerror(errno));
return -1;
}
memset(&user_sockaddr, 0, sizeof(user_sockaddr));
user_sockaddr.nl_family = PF_NETLINK;
user_sockaddr.nl_pid = getpid();
user_sockaddr.nl_groups = MY_GROUP;
retval = bind(sock_fd, (struct sockaddr*)&user_sockaddr, sizeof(user_sockaddr));
if(retval < 0)
{
sprintf(kernel_msg, "bind failed: %s", strerror(errno));
LOGV(strerror(kernel_msg));
printf("bind failed: %s", strerror(errno));
close(sock_fd);
return -1;
}
while (1)
{
nl_msghdr = (struct nlmsghdr*) malloc(NLMSG_SPACE(MAX_SIZE));
if(!nl_msghdr)
{
LOGV(strerror("malloc nlmsghdr error!\n"));
printf("malloc nlmsghdr error!\n");
close(sock_fd);
return -1;
}
memset(nl_msghdr, 0, NLMSG_SPACE(MAX_SIZE));
iov.iov_base = (void*) nl_msghdr;
iov.iov_len = NLMSG_SPACE(MAX_SIZE);
memset(&msghdr, 0, sizeof(msghdr));
msghdr.msg_iov = &iov;
msghdr.msg_iovlen = 1;
recvmsg(sock_fd, &msghdr, 0);
LOGV(NLMSG_DATA(nl_msghdr));
printf("%s\n", NLMSG_DATA(nl_msghdr));
}
close(sock_fd);
return 0;
}

Sending UDP packet to 2 clients and only one receive

(sorry by advance for my English...)
I am working on a network between a PC and a set of Zedboards connected by Ethernet. I use the UDP protocol, and here's my problem:
- All my cards and my PC are correctly connected to a switch and have their own IPs (192.168.1.15 for PC , and 11/12 for cards).
- When I try to send a simple packet with unix sockets with the code below, only the last message is received (but both seem to be send) (plus, no error or warning on compilation)
- If I switch the two sending, it is always the last which arrive at destination so it is not a card problem...
main.c
#include "send_tool.h"
static int PORT;
static char LOCAL_ADDRESS[50];
static SOCKADDR_IN client_list[NB_CLIENTS];
static int uc_sock;
int main(int argc, char **argv)
{
char buffer[BUF_SIZE];
int actual;int i;
memset(buffer,0, sizeof(buffer));
SOCKADDR_IN csin = { 0 };
if(argc < 3)
{
PORT = 2005;
sprintf(LOCAL_ADDRESS, "192.168.1.15");
printf("Valeurs de parametre forcees: %d\t%s\n", PORT, LOCAL_ADDRESS);
}
else
{
PORT = atoi(argv[1]);
sprintf(LOCAL_ADDRESS, argv[2]);
}
uc_sock = init_UC_connection(LOCAL_ADDRESS, PORT);
while(actual < NB_CLIENTS)
{
read_UDP(uc_sock, &csin, buffer);
if(!strncmp(buffer, "free:",5))
{
//add_client(client_list, csin);
client_list[actual].sin_addr.s_addr = csin.sin_addr.s_addr;
client_list[actual].sin_port = csin.sin_port;
client_list[actual].sin_family = csin.sin_family;
memcpy(client_list[actual].sin_zero, csin.sin_zero, 8);
//sprintf(buffer, "salut");
//write_UDP(uc_sock, &client_list[actual], buffer, strlen(buffer));
actual++;
}
}
printf("************************************\n");
printf("0: %s:%d/%d\n", inet_ntoa(client_list[0].sin_addr), ntohs(client_list[0].sin_port), client_list[0].sin_family);
printf("1: %s:%d/%d\n", inet_ntoa(client_list[1].sin_addr), ntohs(client_list[1].sin_port), client_list[1].sin_family);
printf("************************************\n");
sprintf(buffer, "au revoir");
write_UDP(uc_sock, &client_list[0], buffer, strlen(buffer));
write_UDP(uc_sock, &client_list[1], buffer, strlen(buffer));
memset(buffer, 0, sizeof(buffer));
while(read_UDP(uc_sock, &csin, buffer) > 0){}
close(uc_sock);
return 0;
}
send_tool.h
/* STD LIBS */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
//#include <sys/types.h>
//#include <sys/stat.h>
/* SOCKETS */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
/* TIME */
#include <sys/timerfd.h>
#include <sys/time.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#define BUF_SIZE 60000
#define MULTICAST_ADDRESS "224.0.0.1"
#define NB_CLIENTS 2
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct in_addr IN_ADDR;
int init_UC_connection(char LOCAL_ADDRESS[], int port);
void write_UDP(int sock, SOCKADDR_IN *sin, const char *buffer, size_t buff_len);
int read_UDP(int sock, SOCKADDR_IN *sin, char *buffer);
send_tool.c
#include "send_tool.h"
int init_UC_connection(char LOCAL_ADDRESS[], int port)
{
/* UDP so SOCK_DGRAM */
int sock = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN sin = { 0 };
struct timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;
if(sock == -1)
{
perror("socket()");
exit(errno);
}
sin.sin_addr.s_addr = inet_addr(LOCAL_ADDRESS);
sin.sin_port = htons(port);
sin.sin_family = AF_INET;
if(bind(sock,(SOCKADDR *)&sin, sizeof sin) == -1)
{
perror("bind()");
exit(errno);
}
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
perror("Error");
}
return sock;
}
void write_UDP(int sock, SOCKADDR_IN *sin, const char *buffer, size_t buff_len)
{
socklen_t sinsize = 16;//sizeof *sin;
printf("sinsize : %d\n", sinsize);
int n;
size_t i;
if((n=sendto(sock, buffer, buff_len, 0, (SOCKADDR *) sin, sinsize)) < 0)
{
perror("send()");
exit(errno);
}
printf("envoi (sinsize = %d; n = %d)|%s| a %s:%d/%d termine \n", sinsize, n, buffer, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), sin->sin_family);
}
int read_UDP(int sock, SOCKADDR_IN *sin, char *buffer)
{
int n = 0;
socklen_t sinsize = sizeof *sin;
if((n = recvfrom(sock, buffer, BUF_SIZE - 1, 0, (SOCKADDR *) sin, &sinsize)) < 0)
{
perror("recvfrom()");
exit(errno);
}
printf("recu (sinsize = %d; n = %d)|%s| depuis %s:%d/%d termine \n", sinsize, n, buffer, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), sin->sin_family);
return n;
}
client.c
#include "receive_tool.h"
static int PORT;
static char LOCAL_ADDRESS[50];
/* main function, launching the Server application*/
int main(int argc, char **argv)
{
int uc_sock;
char free_msg[30];
memset(free_msg, 0, sizeof(free_msg));
char buffer[60000];
memset(buffer, 0, sizeof(buffer));
if(argc < 3)
{
PORT = 2005;
sprintf(LOCAL_ADDRESS, "192.168.1.12");
//printf("Valeurs de parametre forcees: %d\t%s\n", PORT, LOCAL_ADDRESS);
}
else
{
PORT = atoi(argv[1]);
sprintf(LOCAL_ADDRESS, argv[2]);
}
sprintf(free_msg, "free:%s", LOCAL_ADDRESS);
SOCKADDR_IN server_sin = { 0 }, receive_sin = { 0 };
server_sin.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); // addresse multicast vers les serveurs
server_sin.sin_family = AF_INET;
server_sin.sin_port = htons(PORT);
memset(&server_sin.sin_zero, 0, sizeof(server_sin.sin_zero));
uc_sock = init_UC_connection(LOCAL_ADDRESS, PORT);
write_UDP(uc_sock, &server_sin, free_msg);
time_t chrono_begin;
chrono_begin = time(NULL);
chrono_begin+= 5;
while(time(NULL) <= chrono_begin)
{
if(read_UDP(uc_sock, &receive_sin, buffer)<0) continue;
write_UDP(uc_sock, &server_sin, buffer);
}
close(uc_sock);
return 0;
}
Do you have any idea why this happen?
Thank you for your help.
The problem was caused by the Zedboards which used the same MAC address. Then, the switch sent only to the last IP address connected to the MAC address.
Bye

socket error when using SOCK_RAW and how to accept multiple client with layer 2 communication

soc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); in client side, when run, get == -1 error
if accept function can only use with UDP and TCP higher protocol, how to accept multiple client with layer 2 communication?
where can find the code of accept function, i would like to rewrite it for layer 2.
Updated :
After tried soc = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
also == -1 , get this error
server side and client side both are the same computer, local one
strange is that running server side, it do not have this error, but running client program got error
//#include "stdafx.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
//#include "sock.h"
#define MAX_MESSAGE 21000
#define FD_NUM 5
#define tcp_port 5009
//#pragma comment(lib, "ws2_32.lib")
//#include <winsock2.h>
char host_ip[16] = "127.0.0.1";
void task()
{
struct sockaddr_in local;
int opt;
int soc;
//soc = socket(AF_INET,SOCK_STREAM,0);
soc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (soc==-1) {
printf("socket error\n");
}
// determine ethernet number
/*
struct ifreq ifr;
size_t if_name_len=strlen(if_name);
if (if_name_len<sizeof(ifr.ifr_name)) {
memcpy(ifr.ifr_name,if_name,if_name_len);
ifr.ifr_name[if_name_len]=0;
} else {
printf("interface name is too long");
}
if (ioctl(fd,SIOCGIFINDEX,&ifr)==-1) {
printf("determine ethernet number error\n");
}
int ifindex=ifr.ifr_ifindex;
*/
// mac address
/*target address*/
struct sockaddr_ll socket_address;
/*buffer for ethernet frame*/
void* buffer = (void*)malloc(ETH_FRAME_LEN);
/*pointer to ethenet header*/
unsigned char* etherhead = (unsigned char*)buffer;
/*userdata in ethernet frame*/
unsigned char* data = (unsigned char*)buffer + 14;
/*another pointer to ethernet header*/
struct ethhdr *eh = (struct ethhdr *)etherhead;
int send_result = 0;
/*our MAC address*/
//10:78:d2:ad:90:cb
//0x10,0x78,0xD2,0xAD,0x90,0xCB
unsigned char src_mac[6] = {0x10,0x78,0xD2,0xAD,0x90,0xCB};
/*other host MAC address*/
unsigned char dest_mac[6] = {0x10,0x78,0xD2,0xAD,0x90,0xCB};
/*prepare sockaddr_ll*/
/*RAW communication*/
socket_address.sll_family = PF_PACKET;
/*we don't use a protocoll above ethernet layer
->just use anything here*/
socket_address.sll_protocol = htons(ETH_P_IP);
/*index of the network device
see full code later how to retrieve it*/
socket_address.sll_ifindex = 0;
/*ARP hardware identifier is ethernet*/
socket_address.sll_hatype = ARPHRD_ETHER;
/*target is another host*/
socket_address.sll_pkttype = PACKET_OTHERHOST;
/*address length*/
socket_address.sll_halen = ETH_ALEN;
/*MAC - begin*/
socket_address.sll_addr[0] = 0x10;
socket_address.sll_addr[1] = 0x78;
socket_address.sll_addr[2] = 0xD2;
socket_address.sll_addr[3] = 0xAD;
socket_address.sll_addr[4] = 0x90;
socket_address.sll_addr[5] = 0xCB;
/*MAC - end*/
socket_address.sll_addr[6] = 0x00;/*not used*/
socket_address.sll_addr[7] = 0x00;/*not used*/
memcpy((void*)buffer, (void*)dest_mac, ETH_ALEN);
memcpy((void*)(buffer+ETH_ALEN), (void*)src_mac, ETH_ALEN);
eh->h_proto = 0x00;
int j = 0;
for (j = 46; --j; data[j] = (unsigned char)((int) (255.0*rand()/(RAND_MAX+1.0))));
/*
struct sockaddr_in server;
int len = sizeof(server);
server.sin_family=AF_INET;
server.sin_port=htons(5008);
server.sin_addr.s_addr=inet_addr(host_ip);
int CONN_SOCK = InitSocketTcp(tcp_port);
if(connect(CONN_SOCK, (struct sockaddr*)&server, sizeof(server)) == -1)
{
printf("connection failed\n");
}
else
{
printf("connection ok!\n");
}
*/
while(1)
{
char buff[492] = "\0";
printf("input: ");
scanf("%s", buff);
//send(CONN_SOCK,buff,strlen(buff),0);
/*send the packet*/
send_result = sendto(soc, buff, ETH_FRAME_LEN, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
send_result == -1?printf("send error"):0;
if(buff[0] == 'q')
{
//shutdown(CONN_SOCK, SD_SEND);
//closesocket(CONN_SOCK);
//WSACleanup();
close(soc);
exit(0);
}
}
}
int main()
{
//for(int i=10; i!=0; --i)
//pthread_create();
task();
return 0;
}
Accept() is only used for TCP or UDP (practically it's main use is in tcp), because it establishes a connection. A connection does 3 way handshake in case of tcp and exchanges information such as sequence numbers etc. and is completely identified by a socket (port plus ip address)
In contrast to that you can simply use sendto and receivefrom api's as normally used in case of udp, where each packet may follow a different path to reach destination. You do not require an accept in case of udp communication. The same can be extended to link layer (L2) frames i.e. each side can send or receive at will without actually establishing a connection first.
This should be done using root

Resources