请教抓数据包问题

发布于 2022-07-16 00:07:59 字数 222 浏览 6 评论 9

struct sockaddr_in addr;
len=sizeof(addr);
r = recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len);
这样子收到的是一个完整的数据包,
假如我希望只往buf中放数据包的首部,比如54字节,应该如何处理?

谢谢~~~

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

谜兔 2022-07-22 07:51:16

原帖由 dingdangma 于 2006-3-18 16:15 发表
就是收到的数据包的首部放进buf中,而把数据部分丢弃。
可以这样做吗?还是必须保存一个完整的数据包?

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <netinet/ip.h>
  7. #include <string.h>
  8. #include <netdb.h>
  9. #include <netinet/tcp.h>
  10. #include <netinet/udp.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13. #include <signal.h>
  14. #include <net/if.h>
  15. #include <sys/ioctl.h>
  16. #include <sys/stat.h>
  17. #include <fcntl.h>
  18. #include <linux/if_ether.h>
  19. void die(char *why, int n)
  20. {
  21.   perror(why);
  22.   exit(n);
  23. }
  24. int do_promisc(char *nif, int sock )
  25. {
  26.         struct ifreq ifr;
  27.         
  28.         strncpy(ifr.ifr_name, nif,strlen(nif)+1);
  29.           if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1))
  30.           {        
  31.             die("ioctl", 2);
  32.           }
  33.           ifr.ifr_flags |= IFF_PROMISC;
  34.          
  35.           if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 )
  36.           {
  37.             die("ioctl", 3);
  38.           }
  39. }
  40. char buf[2*32767];
  41. main()
  42. {
  43.         struct sockaddr_in addr;
  44.         struct ethhdr *peth;
  45.         struct iphdr *pip;                                                                                                                                                                        
  46.         struct tcphdr *ptcp;
  47.         struct udphdr *pudp;
  48.         /*add more protocol head here....*/
  49.         
  50.         int sock, r, len;                                                                                                                                                                        
  51.         char *data;
  52.         char *ptemp;
  53.         
  54.         char ss[32], dd[32];     
  55.         int i;
  56.           if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1)
  57.                 die("socket", 1);
  58.         do_promisc("eth0", sock);
  59.   
  60.           for(;;)
  61.         {
  62.                     len = sizeof(addr);
  63.                     r = recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len);
  64.                     buf[r] = 0;
  65.                 ptemp = buf;
  66.                 /*which can get source mac address and destnation address, and which network packet, here is OSI-2, link layer*/
  67.                 peth = (struct ethhdr *)ptemp;
  68.                
  69.                 ptemp += sizeof(struct ethhdr);
  70.                 /*which get IP layer informations, includes which transport protocol, source and destnation IP address...*/               
  71.                     pip = (struct iphdr *)ptemp;
  72.                 /*        
  73.                   * which can get transport layer informations, such as: transport socket port, transport layer includes
  74.                   * TCP, UDP, ICMP, IGMP......, can get which transport protocol from IP header
  75.                   */
  76.                 ptemp += sizeof(struct iphdr);
  77.                 switch(pip->protocol)
  78.                 {
  79.                         case        IPPROTO_TCP:
  80.                                 ptcp = (struct tcphdr *)ptemp;
  81.                                 printf("TCP pkt:n");
  82.                                 /*
  83.                                   * and your service code....
  84.                                   */
  85.                         break;
  86.                         case        IPPROTO_UDP:
  87.                                 pudp = (struct udphdr *)ptemp;
  88.                                     printf("UDP pkt:n len:%d payload len:%d from %s:%d to %s:%dn",
  89.                                                            r,
  90.                                                            ntohs(pudp->len),
  91.                                                            strcpy(ss, inet_ntoa(*(struct in_addr*)&(pip->;saddr))),
  92.                                                            ntohs(pudp->source),
  93.                                                            strcpy(dd, inet_ntoa(*(struct in_addr*)&(pip->;daddr))),
  94.                                                            ntohs(pudp->dest)
  95.                                 );
  96.                                 /*
  97.                                   * and your service code....
  98.                                   */
  99.                         break;
  100.                         case         IPPROTO_ICMP:
  101.                                 printf("ICMP pkt:n");
  102.                         break;
  103.                                 
  104.                         case         IPPROTO_IGMP:
  105.                                 printf("IGMP pkt:n");
  106.                         break;
  107.                         default:
  108.                                 printf("Unkown pkt, protocl:%dn", pip->protocol);
  109.                         break;
  110.                 }
  111.            }        
  112. }

复制代码

这是以前黄山松写的。转过来给你看看应该有帮助。

笑饮青盏花 2022-07-22 07:51:16

呵呵,先谢过再看~~~~
:)

萌辣 2022-07-22 07:51:16

这些功能基本都已经实现,还有两个问题:
1: r = recvfrom(sock,p_map,54, 0, (struct sockaddr *)&addr,&len);
这样是否可以实现只向p_map 中存放每个数据包的前54字节的数据?

2: for (;
{r = recvfrom(sock,(p_map+i),54, 0, (struct sockaddr *)&addr,&len);
    i = i + 54;
}
这样是否可以实现每次在p_map中依次存放54字节的数据,而不会覆盖上次存放的数据?

多谢~~
:)

半窗疏影 2022-07-22 07:51:16

原帖由 dingdangma 于 2006-3-18 18:09 发表
这些功能基本都已经实现,还有两个问题:
1: r = recvfrom(sock,p_map,54, 0, (struct sockaddr *)&addr,&len);
这样是否可以实现只向p_map 中存放每个数据包的前54字节的数据?

2: for (;
{r = ...

1.应该可以.
第2个我不懂你为什么要这么做.

其实收下来个数据包 无论多大.你都可以直接取它的前54字节.何必像你上面的代码那样做.

要走就滚别墨迹 2022-07-22 07:51:16

谢谢版主`~~~

主要是我想实现这样的功能:主进程只负责抓包,放到一个共享内存中; 子进程只负责处理共享内存中的数据包。
如果不让p_map+i,就会覆盖原来收到的数据包。

才开始解除linux下的编程,很多地方都不太懂,请版主多多指教,呵呵:)

烟柳画桥 2022-07-22 07:51:14

原帖由 dingdangma 于 2006-3-18 16:15 发表
就是收到的数据包的首部放进buf中,而把数据部分丢弃。
可以这样做吗?还是必须保存一个完整的数据包?

可以这样做。需要你自己处理。

不及他 2022-07-22 05:30:32

就是收到的数据包的首部放进buf中,而把数据部分丢弃。
可以这样做吗?还是必须保存一个完整的数据包?

平定天下 2022-07-22 05:21:37

>>假如我希望只往buf中放数据包的首部,比如54字节,应该如何处理?

这句话什么意思?

青衫负雪 2022-07-18 08:12:21

请高手们指导下啊,急啊.......

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文