TCP/IP学习--tcp row socket实作


对原始套接口感兴趣还在于它是构建 端口扫描,泛洪攻击,会话拦截  等一系列网络行为的基础。                                                                      

 原始套接口提供普通的TCP和UDP套接口不提供的以下3个能力:

    1.进程 可以读与写ICMP,IGMP等分组。

    2.进程可以读与写内核不处理其协议字段的IPv4数据报。

    3.进程可以使用IP_HDRINCL 套接口选项自行构造IPv4头部。

 

下面的简单的tcp row socket 实现,在centos 4 中编译通过


#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/udp.h>

#define PCKT_LEN 8192

//can create separate header file
//ip header's structs
struct ipheader{
    unsigned char      iph_ihl:5,iph_ver:4;
    unsigned char       iph_tos;
    unsigned short int iph_len;
    unsigned short int iph_ident;
    unsigned char       iph_flag;
    unsigned short int iph_offset;
    unsigned char       iph_ttl;
    unsigned char       iph_protocol;
    unsigned short int iph_chksum;
    unsigned int        iph_sourceip;
    unsigned int        iph_destip;
};
//tcp header's sturcts
struct tcpheader{
    unsigned short int tcph_srcport;
    unsigned short int tcph_destport;
    unsigned int        tcph_seqnum;
    unsigned int       tcph_acknum;        unsigned char      tcph_reserved:4,tcph_offset:4;
    unsigned int       tcp_res1:4,
               tcph_hlen:4,
               tcph_fin:1,
               tcph_syn:1,
               tcph_rst:1,
               tcph_psh:1,
               tcph_ack:1,
               tcph_urg:1,
               tcph_res2:2;
    unsigned short int tcph_win;
    unsigned short int tcph_chksum;
    unsigned short int tcph_urgptr;
};
//check sum function
unsigned short check_sum(unsigned short *buf,int nwords){
    unsigned long sum;
    for(sum = 0; nwords > 0; nwords--)
        sum += *buf++;
    sum = (sum >> 16) + (sum &0xffff);
    sum += (sum  >>16);
    return (unsigned short)(~sum);
}


int main(int argc,char *argv[]) {
    int sockfd;
    char buffer[PCKT_LEN];
    struct ipheader *ip = (struct ipheader *)buffer;
    struct tcpheader *tcp = (struct tcpheader*)(buffer + sizeof(struct ipheader));

    struct sockaddr_in sin,din;
    int one = 1;
    const int *val = &one;
    memset(buffer,0,PCKT_LEN);
    if(argc != 5){
        printf("- Invalid parameters!!!/n");
        printf("- Usage %s <source hostname/ip><source port> <target hostname/ip><target port>/n",argv[0]);
        exit(-1);
    }
    sockfd = socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
    if(sockfd < 0) {
        perror("socket() error");
        exit(-1);
    } else        
        printf("socket() - Using sock_raw socket and udp protocol is OK./n");
    sin.sin_family = AF_INET;
    din.sin_family = AF_INET;
    sin.sin_port = htons(atoi(argv[2]));
    din.sin_port = htons(atoi(argv[4]));
    sin.sin_addr.s_addr = inet_addr(argv[1]);
    sin.sin_addr.s_addr = inet_addr(argv[3]);
   
    ip->iph_ihl = 5;
    ip->iph_ver = 4;
    ip->iph_tos = 16;
    ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
    ip->iph_ident = htons(54321);
    ip->iph_offset = 0;
    ip->iph_ttl = 64;
    ip->iph_protocol = 6; //tcp
    ip->iph_chksum = 0;
    ip->iph_sourceip = inet_addr(argv[1]);
    ip->iph_destip = inet_addr(argv[3]);
   
    tcp->tcph_srcport = htons(atoi(argv[2]));
    tcp->tcph_destport = htons(atoi(argv[4]));
    tcp->tcph_seqnum = htonl(1);
    tcp->tcph_acknum = 0;
    tcp->tcph_offset = 5;
    tcp->tcph_syn = 1;
    tcp->tcph_ack = 0;
    tcp->tcph_win = htons(32767);
    tcp->tcph_chksum = 0;
    tcp->tcph_urgptr = 0;
    ip->iph_chksum = check_sum((unsigned short *)buffer,(sizeof(struct ipheader) + sizeof(struct tcpheader)));
    if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0) {
        perror("setsockopt() error");
        exit(-1);
    } else
        printf("setsockopt() is ok/n");
    printf("Trying ..../n");
    printf("Using raw socket and udp protocol/n");
    printf("Using source ip: %s port: %u,Target ip: %s port: %u./n",argv[1],atoi(argv[2]),argv[3],atoi(argv[4]));
     unsigned int count;
    for(count = 1;count <= 20; count++){
        if(sendto(sockfd,buffer,ip->iph_len,0,(struct sockaddr *)&sin,sizeof(sin)) < 0) {
            perror("sendto() error");
            exit(-1);
        } else {
            printf("Count #%u - sendto() is OK./n",count);
            sleep(2);
        }
    }
    close(sockfd);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值