博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IPv4报文分片代码
阅读量:5309 次
发布时间:2019-06-14

本文共 3662 字,大约阅读时间需要 12 分钟。

IP报文内包装了一个ICMP报文,不过还是没法重组报文。想要练习重组报文似乎得直接抓链路层的包才行。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct iphdr ip; //IP报头 char buf[128]; //ICMP报头 //校验和,网上挖过来的代码 unsigned short checksum(unsigned short *buffer, int size) { unsigned long cksum = 0; while (size > 1) { cksum += *buffer++; size -= sizeof(unsigned short); } if (size) cksum += *(unsigned short*) buffer; cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (unsigned short) (~cksum); } //获取网络地址 int getaddr(const char *name, struct sockaddr_in *addr) { struct addrinfo hint = { 0, AF_INET, SOCK_RAW, IPPROTO_ICMP }; struct addrinfo *res; int rv; if ((rv = getaddrinfo(name, 0, &hint, &res)) != 0) { fprintf(stderr, "error at gethostinfo:%s\n", gai_strerror(rv)); return -1; } memcpy(addr, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); return 0; } //获取原始套接字 int ip_socket() { int rv, sock; if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) { fprintf(stderr, "error at socket:%s\n", strerror(errno)); return -1; } setuid(getuid()); rv = 1; //自己操纵IP报头 if ((rv = setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &rv, sizeof rv) == -1)) { fprintf(stderr, "error at setsockopt:%s\n", strerror(errno)); return -1; } return sock; } void init(const struct sockaddr_in *src, const struct sockaddr_in *dest) { char c = 0, *p; struct icmphdr *icmp = (struct icmphdr *) buf; for (p = (char *) (icmp + 1); p < buf + sizeof buf; ++p) { *p = c++; } //配置ICMP报头 icmp->type = ICMP_ECHO; icmp->code = 0; icmp->checksum = 0; icmp->un.echo.id = getpid(); icmp->un.echo.sequence = 0; icmp->checksum = checksum((unsigned short *) buf, sizeof buf); //配置IP报头,所有单元皆为大端序 ip.version = 4; ip.ihl = 5; ip.tos = 0; ip.tot_len = htons((ip.ihl << 2) + sizeof buf); ip.id = getpid(); ip.frag_off = 0; ip.ttl = 223; ip.protocol = IPPROTO_ICMP; ip.check = 0; memcpy(&ip.saddr, &src->sin_addr, sizeof(src->sin_addr)); memcpy(&ip.daddr, &dest->sin_addr, sizeof(dest->sin_addr)); } //发送分片,last为1时结束 int sendfrag(int sock, const struct sockaddr_in *dest, char *base, uint off, uint size, int last) { char flag; if (last) { flag = 0x40; //DF位, 0100 0000,大端序 } else { flag = 0x60; //MF|DF位,0110 0000,大端序 } int tot_len = sizeof(ip) + size; ip.tot_len = htons(tot_len); ip.frag_off = htons(off >> 3); ip.frag_off |= flag; ip.check = checksum((unsigned short *) &ip, sizeof ip); char sendb[tot_len]; //自己设置IP报头时,MSG_MORE似乎无效,所以还是得拷贝数据 memcpy(sendb, &ip, sizeof ip); memcpy(sendb + sizeof ip, base + off, size); long int rv; if ((rv = sendto(sock, sendb, tot_len, 0, (struct sockaddr*) dest, sizeof(struct sockaddr_in))) == -1) { fprintf(stderr, "error at sendto1:%s\n", strerror(errno)); return -1; } return rv; } int main(int argc, char *argv[]) { struct sockaddr_in src, dest; char buf2[256]; getaddr("127.0.0.1", &src); getaddr(argv[1], &dest); printf("from host:%s --->", inet_ntoa(src.sin_addr)); printf(" to host: %s\n", inet_ntoa(dest.sin_addr)); int sock = ip_socket(); if (sock == -1) { fprintf(stderr, "sock err and exit.\n"); return -1; } init(&src, &dest); uint i, len = sizeof dest; for (i = 0; i < 1024; ++i) { printf("ping dest: %s...", inet_ntoa(dest.sin_addr)); sendfrag(sock, &dest, buf, 0, 32, 0); sendfrag(sock, &dest, buf, 32, 32, 0); sendfrag(sock, &dest, buf, 64, 32, 0); sendfrag(sock, &dest, buf, 96, 32, 1); recvfrom(sock, buf2, 256, 0, (struct sockaddr *) &dest, &len); printf("recved.\n"); sleep(1); } printf("done.\n"); return 0; }

转载于:https://www.cnblogs.com/huyc/archive/2011/10/17/2215601.html

你可能感兴趣的文章
git安装和简单配置
查看>>
C# FTP远程服务器返回错误:(550) 文件不可用(例如,未找到文件,无法访问文件)...
查看>>
面向对象:反射,双下方法
查看>>
利用matplotlib绘画出二特征的散点图
查看>>
RabiitMq
查看>>
WebForm 发送邮箱
查看>>
鼠标悬停提示文本消息最简单的做法
查看>>
# C++中对PI的引用
查看>>
Java面向对象重要关键字
查看>>
美女CEO三十感言--大家都是出来卖的
查看>>
C、JAVA存储管理不同点
查看>>
课后作业-阅读任务-阅读提问-2
查看>>
rtmp服务器以及rtmp推流/拉流/转发
查看>>
面向对象设计中private,public,protected的访问控制原则及静态代码块的初始化顺序...
查看>>
挑战常规--不要这样使用异常
查看>>
malloc函数的用法
查看>>
渐变的参数
查看>>
C#委托详解(3):委托的实现方式大全(续)
查看>>
RaceWeb终于可以在oracle中快速建表了
查看>>
像雾像雨又像风
查看>>