Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26822
  • 博文数量: 42
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 481
  • 用 户 组: 普通用户
  • 注册时间: 2017-03-09 09:24
  • 认证徽章:
个人简介

水滴

文章分类
文章存档

2018年(32)

2017年(10)

我的朋友

分类: LINUX

2018-05-18 17:46:39

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");
}

阅读(46) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册