对原始套接字使用自定义协议

时间:2019-04-08 17:12:58

标签: c sockets networking raw-sockets

我的问题与IP_HDRINCLsetsockopt标志的使用有关。我正在尝试使用原始套接字测试自定义协议的使用。我不确定我在做什么是否正确。我只是想将字符串以及客户端代码附加的ip标头传递给服务器代码。我写的第一个代码是:

Server.c

#include "../cn.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>

int main(int argc, char const *argv[])
{
    int rsfd = socket(AF_INET,SOCK_RAW,253);
    if(rsfd<0)
    {
        perror("Could not create socket");exit(0);
    }
    int val = 1;
    setsockopt(rsfd,IPPROTO_IP,SO_BROADCAST|IP_HDRINCL,&val,sizeof(val));
    char buffer[100];
    struct iphdr *ip;
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.2");
    if(bind(rsfd,(struct sockaddr*)&addr,sizeof(addr))<0)
    {
        perror("Could not bind");exit(0);
    }
    else
        printf("Bound..\n");
    if(recvfrom(rsfd,buffer,100,0,NULL,NULL)<0)
    {
        perror("Could not receive");exit(0);
    }
    else
    {
        printf("Success..\n");
        ip = (struct iphdr*)(buffer);
        char ad[INET_ADDRSTRLEN];
        printf("Protocol No: %d\nTTL: %d\nVersion No: %d\nPacket ID: %d\nSource Address: %s\nChecksum: %d\nLength: %d\n",(int)ip->protocol,(int)ip->ttl,(int)ip->version,(int)ip->id,inet_ntop(AF_INET,&(ip->saddr),ad,INET_ADDRSTRLEN),(int)ip->check,(int)ip->ihl);

    }
    return 0;
}

Client.c

#include "../cn.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>

int main(int argc, char const *argv[])
{
    int rsfd = socket(AF_INET,SOCK_RAW,253);
    if(rsfd<0)
    {
        perror("Could not create socket");exit(0);
    }
    int val = 1;
    setsockopt(rsfd,IPPROTO_IP,SO_BROADCAST|IP_HDRINCL,&val,sizeof(val));
    char buffer[100];
    struct iphdr* ip;
    ip = (struct iphdr*)buffer;
    ip->protocol = 253;
    ip->version = 4;
    ip->id = 0;
    ip->saddr = 0;
    ip->daddr = inet_addr("127.0.0.2");
    printf("Enter a string..\n");
    scanf("%s",buffer+60); //trying to insert a string at buffer+60 position
    printf("Entered: %s\n",buffer+60);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.2");
    if(sendto(rsfd,buffer,100,0,(struct sockaddr*)&addr,sizeof(addr))<0)
        perror("Could not send");
    else
        printf("Sent successfully..\n");
    return 0;
}

程序正在运行,没有任何错误,但是当我尝试在偏移量60处打印消息时,它清除了一些垃圾值。然后,我尝试打印该字符缓冲区中的所有值,但令我惊讶的是,实际消息的偏移量为80,这意味着距插入位置正好20个字节。经过更多实验后,我意识到在服务器端收到的ip头根本不是用户定义的头。网络层本身正在吸引它!但是IP_HDRINCL选项是否应该保留附加IP标头的网络层?我说的是根据我对this的解释。 我在哪里做错了?另外,任何人都可以在原始套接字上提供一些好的教程(尤其是有关自定义协议实现的教程)吗?

0 个答案:

没有答案