linux rawsocket java_Linux通信-RawSocket通信

Linux-Rawsoket通信

为了满足能够从2层直接读取相应数据编写了raw通讯接口, 直接代码。

1. server

#include pthread.h

#include sys/socket.h

#include sys/ioctl.h

#include sys/time.h

#include asm/types.h

#include math.h

#include string.h

#include stdlib.h

#include unistd.h

#include signal.h

#include linux/if.h

#include linux/if_packet.h

#include linux/if_ether.h

#include linux/if_arp.h

#include arpa/inet.h

#include stdio.h

#include "rawsend.h"

#include "MessageFrame.h"

#include "ber_decoder.h"

int sock_fd = 0;

char *ifname;

int running = 1;

struct raw_result server_result;

int open_socket(const char *ifname)

{

struct ifreq ifr;

int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_WSMP));

if (sock < 0){

exit(EXIT_FAILURE);

}

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

ioctl(sock, SIOCGIFFLAGS, &ifr);

ifr.ifr_flags |= IFF_PROMISC;

ioctl(sock, SIOCGIFFLAGS, &ifr);

return sock;

}

void close_socket(int sock)

{

struct ifreq ifr;

/* reset promiscuous mode */

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

ioctl(sock_fd, SIOCGIFFLAGS, &ifr);

ifr.ifr_flags &= ~IFF_PROMISC;

ioctl(sock_fd, SIOCSIFFLAGS, &ifr);

shutdown(sock_fd, SHUT_RD);

close(sock_fd);

}

void print_mac(const char *addr)

{

int i;

for (i = 0; i < ETH_ALEN - 1; i++){

printf("%02hhx:", addr[i]);

}

printf("%02hhx\n", addr[ETH_ALEN - 1]);

}

int interface_index(int sock, char *ifname)

{

struct ifreq ifr;

int i;

/* retrieve source ethernet interface index */

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) < 0)

return -EXIT_FAILURE;

return ifr.ifr_ifindex;

}

int interface_addr(int sock, char *ifname, char *addr)

{

struct ifreq ifr;

/* retrieve corresponding source MAC */

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

if (ioctl(sock_fd, SIOCGIFHWADDR, &ifr) < 0){

return -EXIT_FAILURE;

}

memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);

return EXIT_SUCCESS;

}

void sigint(int signum)

{

if (!running){

exit(EXIT_FAILURE);

}

running = 0;

}

double timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1)

{

double ret;

long int diff;

diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);

result->tv_sec = diff / 1000000;

result->tv_usec = diff % 1000000;

ret = diff;

ret /= 1000000.0;

return ret;

}

int main(int argc, char *argv[])

{

unsigned char *buff = (void *)malloc(PACKET_SIZE);

unsigned char *data_ptr = buff + ETH_HLEN;

unsigned char src_mac[ETH_ALEN];

struct ethhdr *eth_hdr = (struct ethhdr *)buff;

struct sockaddr_ll s_addr;

struct timeval begin, end, elapsed;

struct raw_result *result = (struct raw_result *)(data_ptr + sizeof(END_OF_STREAM));

double diff;

int if_index = 0, recv, i, seq;

if (argc < 2)

{

printf("Missing arguments.\n"

"%s [ifname] \n",argv[0]);

exit(EXIT_FAILURE);

}

ifname = argv[1];

/* open socket */

if ((sock_fd = open_socket(ifname)) < 0){

exit(EXIT_FAILURE);

}

/* get ethernet interface index */

if ((if_index = interface_index(sock_fd, ifname)) < 0){

exit(EXIT_FAILURE);

}

/* get ethernet interface address */

if (interface_addr(sock_fd, ifname, src_mac) < 0){

exit(EXIT_FAILURE);

}

/* prepare sockaddr_ll */

memset(&s_addr, 0, sizeof(s_addr));

s_addr.sll_family   = AF_PACKET;

s_addr.sll_protocol = htons(ETH_P_WSMP);

s_addr.sll_ifindex  = if_index;

/* bind to interface */

if (bind(sock_fd, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1){

exit(EXIT_FAILURE);

}

/* enable signal */

signal(SIGINT, sigint);

printf("listening on ");

print_mac(src_mac);

while (running) {

recv = recvfrom(sock_fd, buff, PACKET_SIZE, 0, NULL, NULL);

if (recv <= 0){

continue;

}else{

print_string_hex(buff, recv);

}

}

return EXIT_SUCCESS;

}

2. client

#include pthread.h

#include sys/socket.h

#include sys/ioctl.h

#include sys/time.h

#include asm/types.h

#include math.h

#include string.h

#include stdlib.h

#include unistd.h

#include signal.h

#include linux/if.h

#include linux/if_packet.h

#include linux/if_ether.h

#include linux/if_arp.h

#include arpa/inet.h

#include stdio.h

#include "rawsend.h"

struct raw_result client_result;

int sock_fd = 0;

unsigned char* out_buff = NULL;

unsigned char* in_buff = NULL;

unsigned char snd_mac[6];

char *src_ifname;

char *dst_ifname;

long total_sent_packets = 0;

long total_recv_packets = 0;

long total_sent_bytes = 0;

int running = 1, waiting = 1;

int open_socket(const char *ifname)

{

struct ifreq ifr;

int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_WSMP));

if (sock < 0){

exit(EXIT_FAILURE);

}

/* set promiscuous mode */

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

ioctl(sock, SIOCGIFFLAGS, &ifr);

ifr.ifr_flags |= IFF_PROMISC;

ioctl(sock, SIOCGIFFLAGS, &ifr);

return sock;

}

void close_socket(int sock)

{

struct ifreq ifr;

/* reset promiscuous mode */

strncpy(ifr.ifr_name, src_ifname, IFNAMSIZ);

ioctl(sock_fd, SIOCGIFFLAGS, &ifr);

ifr.ifr_flags &= ~IFF_PROMISC;

ioctl(sock_fd, SIOCSIFFLAGS, &ifr);

shutdown(sock_fd, SHUT_RD);

close(sock_fd);

}

void print_mac(const char *addr)

{

int i;

for (i = 0; i < ETH_ALEN - 1; i++){

printf("%02hhx:", addr[i]);

}

printf("%02hhx\n", addr[ETH_ALEN - 1]);

}

int interface_index(int sock, char *ifname)

{

struct ifreq ifr;

int i;

/* retrieve source ethernet interface index */

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) < 0){

return -EXIT_FAILURE;

}

return ifr.ifr_ifindex;

}

int interface_addr(int sock, char *ifname, char *addr)

{

struct ifreq ifr;

/* retrieve corresponding source MAC */

strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

if (ioctl(sock_fd, SIOCGIFHWADDR, &ifr) < 0){

return -EXIT_FAILURE;

}

memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);

return EXIT_SUCCESS;

}

void sigint(int signum)

{

if (!running){

exit(EXIT_FAILURE);

}

running = 0;

}

void sigalarm(int signum)

{

if (!running){

exit(EXIT_FAILURE);

}

running = 0;

}

int main(int argc, char *argv[])

{

pthread_t thread;

out_buff = (void*)malloc(PACKET_SIZE);

unsigned char *data_ptr = out_buff + ETH_HLEN;

unsigned char src_addr[ETH_HLEN], dst_addr[ETH_HLEN];

struct ethhdr *out_hdr = (struct ethhdr *)out_buff;

struct sockaddr_ll s_addr;

struct timeval begin, end, elapsed;

double diff;

int i, sent, rate, interval, timeout = 0, src_idx, dst_idx;

src_ifname = argv[1];

/* open raw socket */

if ((sock_fd = open_socket(src_ifname)) < 0){

exit(EXIT_FAILURE);

}

/* prepare source interface */

if ((src_idx = interface_index(sock_fd, src_ifname)) < 0){

exit(EXIT_FAILURE);

}

if (interface_addr(sock_fd, src_ifname, src_addr) < 0){

exit(EXIT_FAILURE);

}

memset(dst_addr, 0xff, ETH_HLEN);

/* prepare sockaddr_ll */

memset(&s_addr, 0, sizeof(s_addr));

s_addr.sll_family   = AF_PACKET;

s_addr.sll_protocol = htons(ETH_P_ALL);

s_addr.sll_ifindex  = src_idx;

if (bind(sock_fd, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0){

exit(EXIT_FAILURE);

}

/* enable signals */

signal(SIGINT, sigint);

signal(SIGALRM, sigalarm);

if (timeout){

alarm(timeout);

}

/* prepare ethernet header */

memcpy(out_hdr->h_dest, dst_addr, ETH_ALEN);

memcpy(out_hdr->h_source, src_addr, ETH_ALEN);

out_hdr->h_proto= htons(ETH_P_WSMP);

/* fill ethernet payload with some data */

for (i = 0; i < PACKET_SIZE - ETH_HLEN; i++){

data_ptr[i] = (unsigned char)(1);

}

printf("sending packets\n");

memcpy(s_addr.sll_addr, dst_addr, ETH_ALEN);

while (running) {

*(int *)data_ptr = htonl(client_result.sequence++);

sent = sendto(sock_fd, out_buff, PACKET_SIZE, 0, (struct sockaddr *)&s_addr, sizeof(s_addr));

if(sent){

printf("sending packets sucess\n");

print_string_hex(out_buff, sent);

}

sleep(5);

}

close_socket(sock_fd);

return EXIT_SUCCESS;

}

3 头文件

#define PACKET_SIZE 1000

#ifndef ETH_P_WSMP

#define ETH_P_WSMP    0x88DC

#endif

void print_string_hex(char *buf, unsigned short length)

{

int i =0;

printf("\n\t\t");

for( i = 0; i < length; i++){

printf(" %02X", (buf[i]&0xFF));

if( (i + 1) % 16 == 0 )

{

printf("\n\t\t");

}

}

printf("\n\n");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值