pf-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 752959
  • 博文数量: 144
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1150
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-17 14:32
个人简介

小公司研发总监,既当司令也当兵!

文章分类

全部博文(144)

相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: linux

2015-06-03 22:03:19

1.介绍
在linux中提供了pf_packet接口可以操作链路层的数据。
 
2.使用方法
定义一个pf_packet = socket(pf_socket, sock_raw, htons(eth_p_rarp));
就可以利用函数sendto和recefrom来读取和发送链路层的数据包了(当然,发送arp包,上面第三个参数要变为htons(eth_p_arp),或者ip的包为eth_p_ip,可查看文件/usr/include/linux/if_ether.h文件看到所有支持的协议)。
 
3.在使用sock_raw, sock_dgram和sock_packet的区别
在socket的第一个参数使用pf_packet的时候,上述三种socket的类型都可以使用。但是有区别。
(1)使用sock_raw发送的数据必须包含链路层的协议头,接受得到的数据包,包含链路层协议头。而使用sock_dgram则都不含链路层的协议头。
(2)sock_packet也是可以使用的,但是已经废弃,以后不保证还能支持,不推荐使用。
(3)在使用sock_raw或sock_dgram和sock_packet时,在sendto和recvfrom中使用的地址类型不同,前两者使用sockaddr_ll类型的地址,而后者使用sockaddr类型的地址。
(4)如socket的第一个参数使用pf_inet,第二个参数使用sock_raw,则可以得到原始的ip包。
 
4.下面的例子是一个简单的arp协议的server程序
server程序一开始获得除lo接口以外接口的mac地址,等待arp request请求的到来,如果请求的是自己的mac地址,则向客户端发送arp reply,回送自己的ip地址。应我使用的地方,一台机器的ip地址每次dhcp以后都会变。所以该程序还是有一些用处。

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/time.h>
  3. #include <time.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/if_ether.h>
  7. #include <net/if_arp.h>
  8. #include <netinet/in.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <unistd.h>
  12. #include <errno.h>
  13. #include <netinet/if_ether.h>
  14. #include <net/if_arp.h>
  15. #include <net/if.h>
  16. #include <netinet/in.h>
  17. #include <arpa/inet.h>
  18. #include <sys/ioctl.h>
  19. #include <netpacket/packet.h>

  20. //#include <cstdlib>
  21. /* args: yiaddr - what ip to ping
  22.  * ip - our ip
  23.  * mac - our arp address
  24.  * interface - interface to use
  25.  * retn: 1 addr free
  26.  * 0 addr used
  27.  * -1 error
  28.  */
  29. /* fixme: match response against chaddr */
  30. struct arpmsg
  31. {
  32.     struct ethhdr ethhdr; /* ethernet header */
  33.     u_short htype; /* hardware type (must be arphrd_ether) */
  34.     u_short ptype; /* protocol type (must be eth_p_ip) */
  35.     u_char hlen; /* hardware address length (must be 6) */
  36.     u_char plen; /* protocol address length (must be 4) */
  37.     u_short operation; /* arp opcode */
  38.     u_char shaddr[6]; /* sender's hardware address */
  39.     u_char sinaddr[4]; /* sender's ip address */
  40.     u_char thaddr[6]; /* target's hardware address */
  41.     u_char tinaddr[4]; /* target's ip address */
  42.     u_char pad[18]; /* pad for min. ethernet payload (60 bytes) */
  43. };
  44. /* miscellaneous defines */
  45. #define mac_bcast_addr (uint8_t *) "/xff/xff/xff/xff/xff/xff"
  46. #define opt_code 0
  47. #define opt_len 1
  48. #define opt_data 2

  49. struct interface_info
  50. {
  51.     char ifname[64];
  52.     unsigned char ip[4];
  53.     unsigned char mac[6];
  54. };

  55. struct interface_info if_info[10];

  56. int eth_num = 0;

  57. void print_mac(unsigned char *mac_addr)
  58. {
  59.     int i;
  60.     for (i = 0; i < 6; i)
  61.     {
  62.         printf("x", mac_addr[i]);
  63.         if (i != 5)
  64.             printf(":");
  65.     }
  66.     printf("/n");
  67. }

  68. void print_ip(unsigned char *ip_addr)
  69. {
  70.     int i;
  71.     for (i = 0; i < 4; i)
  72.     {
  73.         printf("%d", ip_addr[i]);
  74.         if (i != 3)
  75.             printf(".");
  76.     }
  77.     printf("/n");
  78. }

  79. int get_iface_index(int fd, const char *interface_name)
  80. {
  81.     struct ifreq ifr;
  82.     memset(&ifr, 0, sizeof(ifr));
  83.     strcpy(ifr.ifr_name, interface_name);
  84.     if (ioctl(fd, siocgifindex, &ifr) == -1)
  85.     {
  86.         return (-1);
  87.     }
  88.     return ifr.ifr_ifindex;
  89. }

  90. int get_interfaces()
  91. {
  92.     int sock;
  93.     int len = 64;
  94.     int last_len = 0;
  95.     char *pbuff = null;
  96.     int interface_num = 0;
  97.     int i;

  98.     struct ifconf interface_conf;
  99.     struct ifreq ifreq1;
  100.     struct sockaddr_in *psockaddr_in = null;

  101.     if ((sock = socket(pf_inet, sock_dgram, 0)) < 0)
  102.     {
  103.         perror("could not create socket for geting interface info");
  104.         exit(1);
  105.     }

  106.     while (1)
  107.     {
  108.         pbuff = (char *)malloc(len);
  109.         interface_conf.ifc_len = len;
  110.         interface_conf.ifc_buf = pbuff;
  111.         if (ioctl(sock, siocgifconf, &interface_conf) < 0)
  112.         {
  113.             perror("ioctl error");
  114.         }
  115.         else
  116.         {
  117.             if (interface_conf.ifc_len == last_len)
  118.             {
  119.                 break;
  120.             }
  121.             else
  122.             {
  123.                 last_len = interface_conf.ifc_len;
  124.             }
  125.         }
  126.         len = 2 * sizeof(struct ifreq);
  127.         free(pbuff);
  128.     }

  129.     interface_num = last_len / sizeof(struct ifreq);

  130.     for (i = 0; i < interface_num; i)
  131.     {
  132.         strcpy(ifreq1.ifr_name, interface_conf.ifc_ifcu.ifcu_req[i].ifr_name);
  133.         if (strcmp(ifreq1.ifr_name, "lo") == 0)
  134.         {
  135.             continue;
  136.         }
  137.         if (ioctl(sock, siocgifhwaddr, &ifreq1) < 0)
  138.         {
  139.             continue;
  140.         }
  141.         memcpy(if_info[eth_num].mac, ifreq1.ifr_hwaddr.sa_data, 6);
  142.         strcpy(if_info[eth_num].ifname, ifreq1.ifr_name);
  143.         psockaddr_in = (struct sockaddr_in *)&interface_conf.ifc_req[i].ifr_addr;
  144.         memcpy(if_info[eth_num].ip, &(psockaddr_in->sin_addr.s_addr), 4);
  145.         printf("interface name: %s", if_info[eth_num].ifname);
  146.         printf(" ip address: ");
  147.         print_ip(if_info[eth_num].ip);
  148.         printf(" mac address:");
  149.         print_mac(if_info[eth_num].mac);
  150.         eth_num;
  151.     }

  152.     free(pbuff);
  153.     close(sock);
  154. }

  155. int equal_mac(unsigned char *mac1, unsigned char *mac2)
  156. {
  157.     int i;

  158.     for (i = 0; i < 6; i)
  159.     {
  160.         if (mac1[i] != mac2[i])
  161.             return 0;
  162.     }
  163.     return 1;
  164. }

  165. int main()
  166. {
  167.     int timeout = 2;
  168.     int optval = 1;
  169.     int s; /* socket */
  170.     int rv = 1; /* return value */
  171.     struct sockaddr_ll addr; /* for interface name */
  172.     struct arpmsg arp;
  173.     struct arpmsg *parp;

  174.     fd_set fdset;
  175.     struct timeval tm;
  176.     time_t prevtime;
  177.     u_int32_t ip;
  178.     u_int32_t yiaddr;
  179.     struct in_addr my_ip;
  180.     struct in_addr dst_ip;

  181.     struct sockaddr_ll from;
  182.     int lllen;

  183.     char buff[2000];
  184.     int nlen;
  185.     char szbuffer[4096];
  186.     int i;

  187.     if ((s = socket(pf_packet, sock_raw, htons(eth_p_rarp))) == -1)
  188.     {
  189.         printf("could not open raw socket/n");
  190.         return -1;
  191.     }

  192.     if (setsockopt(s, sol_socket, so_broadcast, &optval, sizeof(optval)) == -1)
  193.     {
  194.         printf("could not setsocketopt on raw socket/n");
  195.         close(s);
  196.         return -1;
  197.     }

  198.     memset(&addr, 0, sizeof(addr));
  199.     addr.sll_family = af_packet;
  200.     addr.sll_ifindex = get_iface_index(s, "eth0");
  201.     addr.sll_protocol = htons(eth_p_arp);

  202.     if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
  203.     {
  204.         perror("getsockname");
  205.         return;
  206.     }

  207.     printf("go into get_interfaces\n");
  208.     get_interfaces();

  209.     printf("out get_interfaces\n");
  210.     memset(szbuffer, 0, sizeof(szbuffer));
  211.     lllen = sizeof(from);
  212.     while ((nlen = recvfrom(s, szbuffer, sizeof(szbuffer), msg_trunc, (struct sockaddr *)&from, &lllen)) > 0)
  213.     {
  214.         parp = (struct arpmsg *)szbuffer;
  215.         printf("the request is from");
  216.         printf(" [x:x:x:x:x:x]\n", from.sll_addr[0], from.sll_addr[1],
  217.                from.sll_addr[2], from.sll_addr[3], from.sll_addr[4], from.sll_addr[5]);
  218.         print_ip(parp->sinaddr);

  219.         /* send arp request */
  220.         memset(&arp, 0, sizeof(arp));
  221.         memcpy(arp.ethhdr.h_dest, parp->shaddr, 6); // mac da
  222.         memcpy(arp.ethhdr.h_source, parp->thaddr, 6); // mac sa
  223.         arp.ethhdr.h_proto = htons(eth_p_rarp); // protocol type (ethernet)
  224.         arp.htype = htons(arphrd_ether); // hardware type
  225.         arp.ptype = htons(eth_p_ip); // protocol type (arp message)
  226.         arp.hlen = 6; // hardware address length
  227.         arp.plen = 4; // protocol address length
  228.         arp.operation = htons(4); // rarp reply code
  229.         memcpy(arp.sinaddr, if_info[i].ip, 4); // source ip address
  230.         memcpy(arp.shaddr, parp->thaddr, 6); // source hardware address
  231.         memcpy(arp.tinaddr, parp->sinaddr, 4); // target ip address
  232.         memcpy(arp.thaddr, parp->shaddr, 6);

  233.         printf("send reply to requsted\n");
  234.         if (sendto(s, &arp, sizeof(arp), 0, (struct sockaddr *)&from, sizeof(from)) < 0)
  235.         {
  236.             perror("unabele to send arp request");
  237.             return 0;
  238.         }
  239.         else
  240.             printf("send reply/n");
  241.     }
  242.     close(s);
  243.     return 0;
  244. }


阅读(5152) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图