免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3991 | 回复: 11

[内核入门] 请大家帮帮忙,真的是不会了,本来想做个抓包工具的,结果卡这里了 [复制链接]

论坛徽章:
0
发表于 2014-07-10 14:17 |显示全部楼层
本人刚接触linux没多长时间,基本就是小白,狂爱iptables,下面的问题可能对高手来说是愚蠢的,请别嘲笑我正在努力。我想做个抓包的工具,为的是对7层工作有个直接的认识,自己动手学到的东西多。但是抓包之前要看到包,所以卡在这里了,望大家帮忙,查了一星期,度娘和这里都是东一句西一句我是月学月糊涂,真的是不会了所以一口气问了一大堆。
首先:iptables -A OUTPUT -j NFQUEUE
下面的代码有部分减少,减少长度,为了不让大家看着心烦
static u_int32_t print_pkt (struct nfq_data *tb)
{
int id = 0;
struct nfqnl_msg_packet_hw *hwph;
int ret;
unsigned char *data;

hwph = nfq_get_packet_hw(tb);
if (hwph) {
int i, hlen = ntohs(hwph->hw_addrlen);

printf("hw_src_addr=");
第一个问题,非常奇怪,将output转到nfqueue时for就不输出,只有再加上input转到nfqueue时,才输出我路由的mac,而且mac值是正确的,为什么hw_addr是进来包的来源mac,那进来包的目的mac怎么获得,那么出去包的来源和目的mac又怎么获得那?
for (i = 0; i < hlen-1; i++)
printf("%02x:", hwph->hw_addr[i]);
printf("%02x ", hwph->hw_addr[hlen-1]);
}
ret = nfq_get_payload(tb, &data);
if (ret >= 0)
printf("payload_len=%d \n", ret);
//******************************************************************************************
struct iphdr *ip_1;
第二个问题,感觉data复值给ip就得到ip头,附值给tcp就得到tcp头,附值给ethhdr就得到mac头,因为此程序结果不对,所以不知道自己的感觉对不对,我现在都不知道data到底是什么样子,请高手指点我的感觉对吗?
ip_1=(struct iphdr *)data;

printf("check: %d \n",ip_1->check); //ip头检查码
第三个问题,我想把frag_off分3部分输出,第一部分是frag_off的二进制的第二位,第二部分是二进制第三位,最后一部分就是frag_off剩余的,不知道printf里怎么写
printf("frag_off: \n",ip_1->frag_off); //3个标志位和分段偏移数
printf("id: %d\n",ntohs(ip_1->id));
//******************************************************************************************
struct tcphdr * tcp_1;
tcp_1=(struct tcphdr *)data;
printf("seq: %d \n",tcp_1->seq)
printf("source: %d %d\n",tcp_1->source,ntohs(tcp_1->source));
第四个问题,不知道怎么判断,什么时候需要ntohs,上面的seq和source和dest要不要用ntohl或者ntohs,为什么
第五个问题,我ping我的路由,ping -c 1 192.168.0.1,结只是果是本地放出端口永远是69,ping是icmp包呀,怎么tcp也跟着变动
printf("dest: %d %d \n",tcp_1->dest,ntohs(tcp_1->dest));
//******************************************************************************************
struct ethhdr *eth1;
eth1=(struct ethhdr *)data;
unsigned char *ipsd=(unsigned char *)&eth1->h_source;
第六个问题,这才是核心问题,下面输出的mac号都不是我主机和路由的mac,不知道怎么改了,真不会了
printf("h_source: %02X:%02X:%02X:%02X:%02X:%02X \n",ipsd[0],ipsd[1],ipsd[2],ipsd[3],ipsd[4],ipsd[5]);
printf("source : %02x:%02x:%02x:%02x:%02x:%02x\n",eth1->h_source);
ipsd=(unsigned char *)&eth1->h_dest;
printf("h_dest: %02x:%02x:%02x:%02x:%02x:%02x \n",ipsd[0],ipsd[1],ipsd[2],ipsd[3],ipsd[4],ipsd[5]);
printf("dest : %02x:%02x:%02x:%02x:%02x:%02x\n",eth1->h_dest);
//******************************************************************************************
return id;
}

////////////////////下面的请高手不用看,贴上他只是为了完整性
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
struct nfq_data *nfa, void *data)
{u_int32_t id = print_pkt(nfa);
return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}
int main(int argc, char **argv)
{
struct nfq_handle *h;
struct nfq_q_handle *qh;
struct nfnl_handle *nh;
int fd;
int rv;
char buf[4096] __attribute__ ((aligned));

printf("opening library handle\n");
h = nfq_open();
nfq_unbind_pf(h, AF_INET);
nfq_bind_pf(h, AF_INET);
qh = nfq_create_queue(h, 0, &cb, NULL);

nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff);
fd = nfq_fd(h);
while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0)
nfq_handle_packet(h, buf, rv);
}
return 0;
}

论坛徽章:
0
发表于 2014-07-10 14:18 |显示全部楼层
自己定,望大家帮着看看,谢谢

论坛徽章:
0
发表于 2014-07-10 21:46 |显示全部楼层
本帖最后由 黎明748 于 2014-07-10 21:51 编辑

第一个问题,不明意思。
第二个问题,我不知道你这个data是什么意思,从你代码看data是IP头的地址。ip_1=(struct iphdr *)data;tcp_1=(struct tcphdr *)(data+ip_1.ihl<<2);计算以太网头部类似,貌似数据包先指向以太网首部的吧。

第三个问题,printf("frag_off: %d\n",ip_1->frag_off&0x1);
                  printf("frag_off: %d\n",(ip_1->frag_off&0x2)>> 1);
                  printf("frag_off: %d\n",ip_1->frag_off>>2);
第四个问题,数据包都是网络字节序,本地用都加ntohl或者ntohs。
第五个问题,不明。既然是ICMP包。哪来的TCP头。
第六个问题,还是网络字节序的问题。加ntohl或者ntohs。

话说你这程序可以用吗?

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
发表于 2014-07-10 22:52 |显示全部楼层
回复 1# wantaugust
你不但程序不有问题,你IP协议栈都不清楚。
建议你先不写程程序了,学TCP/IP协议的最好办法是用Wireshark抓包来看看,数据包的结构,字段都会解析,说明得很清楚。结合TCP/IP的书就更好了。
你的解析过程错得很离谱,data怎么一会解析成IP头一会解析成TCP头的呢,TCP头是在IP头后面的!别外,你根本没有解析IP头的含义,PING是ICMP协议,你就去强转成TCP头。
不想一个一个问题回答了,因为错得太离谱了。

   

论坛徽章:
0
发表于 2014-07-11 09:33 |显示全部楼层
非常感谢,但是最后一个问题还是不行回复 3# 黎明748


   

论坛徽章:
0
发表于 2014-07-11 09:47 |显示全部楼层
回复 4# Tinnal

非常感谢回答我的问题,
7层的知识这学期都学了,我用wireshark也验证了,
代码里有ip tcp udp icmp mac的部分,只是贴代码的时候怕有人看着头疼,所以砍了一部分,实际上ping的时候我只看icmp的那部分输出,握手的时候我只看tcp的部分,但是我发现ping的时候tcp的部分也有奇怪的输出
还有您说的“ata怎么一会解析成IP头一会解析成TCP头的呢”,没错,这正是我的第二个问题,data里到底有什么。我怀疑data是一个类似于结构体的东西,我怀疑是这样的:
struct data
{mac头;ip头;tcp头;udp头;icmp头};
当把他赋值给tcphdr的话,那么data就把他里面的tcp头的部分数据传给tcphdr
   

论坛徽章:
0
发表于 2014-07-11 10:37 |显示全部楼层
本帖最后由 inurl 于 2014-07-11 10:38 编辑

  你这个抓包的原理是什么,流程是怎么走的

论坛徽章:
0
发表于 2014-07-11 11:14 |显示全部楼层
回复 7# inurl

先用queue把包拿到,那后在用户空间里把包赋值给data,然后把data在给具体的iphdr
   

论坛徽章:
0
发表于 2014-07-12 08:46 |显示全部楼层
估计是我想错了, printf("payload_len=%d \n", ret);输出是40,可能data中只有ip和tcp的头,但是不知道怎么从data中得到tcp或者udp的头。因为我在tcp的代码段怎么改,输出结果和wireshark都不一样


这个官网上的定义:
int nfq_get_payload         (         struct nfq_data *          nfad,
                unsigned char **          data         
        )                        

nfq_get_payload - get payload

Parameters:
            nfad         Netlink packet data handle passed to callback function
            data         Pointer of pointer that will be pointed to the payload

Retrieve the payload for a queued packet. The actual amount and type of data retrieved by this function will depend on the mode set with the nfq_set_mode() function.

Returns:
    -1 on error, otherwise > 0.

Definition at line 1028 of file libnetfilter_queue.c.


struct nfq_data {
         struct nfattr **data;
};

struct nfattr是什么我没找到

论坛徽章:
0
发表于 2014-07-13 11:38 |显示全部楼层
回复 3# 黎明748
data+ip_1.ihl<<2我明白了,但是请问ip_1.ihl为什么要乘4那,
直接在data上加头长不对吗?

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP