请问用libpcap收到的包怎么转发出去?

发布于 2022-07-22 20:36:49 字数 17310 浏览 7 评论 0

我用libpcap收到的包想用libnet 转发出去,但好像不行。
代码如下:
#include <stdio.h>
#include <pcap.h>
#include <netdb.h>
#include <libnet.h>

#define LIBNET_IP_H 20

typedef struct _et_header    //以太网头部
{
    unsigned char   eh_dst[6];  
    unsigned char   eh_src[6];
    unsigned short  eh_type;
}ET_HEADER;

typedef struct _ip_header
{
    char m_ver_hlen;      //4位版本号,4位ip头部长
char m_tos;
unsigned short m_tlen;
    unsigned short m_ident;
    unsigned short m_flag_frag;     //3位标志位(1位未用位,1位DF,1位MF),13位片断偏移量
char m_ttl;
char m_protocol;
unsigned short m_cksum;
unsigned int  m_sIP;
    unsigned int m_dIP;
}IP_HEADER;

typedef struct _tcphdr //定义TCP首部
{
unsigned short src_port; //16位源端口
unsigned short dest_port; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ack; //32位确认号
unsigned char lenres; //4位首部长度/6位保留字
unsigned char flag; //6位标志位
unsigned short windows; //16位窗口大小
unsigned short sum; //16位校验和
unsigned short urgent; //16位紧急数据偏移量
}TCP_HEADER;

libnet_t *l;

//#define MY_FILTER "ldh [12] n jeq #ETHERTYPE_IP, L1, L2 n L1: ret #TRUE n L2: ret #0 n"
//#define MY_FILTER "port 80"

void DecodeEthPkt(u_char * user, const struct pcap_pkthdr * pkthdr, const u_char  * pkt)
{
//printf("I get one packet! n");
ET_HEADER *lpEthdr;
struct in_addr addr={0};
char source_ip[20]={0},dest_ip[20]={0};

int c;
libnet_ptag_t t;
u_short payload_s;
int ip_total_len;
int ip_header_len;
int tcp_head_len;
TCP_HEADER * pTcpHeader;
char * p_data;

lpEthdr = (ET_HEADER *)pkt;
if(lpEthdr->eh_type!=htons(0x0800))     //判断是否为IP包
         return;

//取源地址和目的地址
IP_HEADER *lpIphdr=(IP_HEADER *)((char *)pkt+sizeof(ET_HEADER));

  memset(&addr,0,sizeof(struct in_addr));
  addr.s_addr=lpIphdr->m_sIP;
  memcpy(source_ip,(char *)inet_ntoa(addr),strlen((char *)inet_ntoa(addr)));

  memset(&addr,0,sizeof(struct in_addr));
  addr.s_addr=lpIphdr->m_dIP;
  memcpy(dest_ip,(char *)inet_ntoa(addr),strlen((char *)inet_ntoa(addr)));

   if( ( strcmp ( source_ip , "192.168.0.115" ) == 0 ) && ( strcmp ( dest_ip ,"192.168.0.31"  ) == 0 ) )
  {
   printf("There is a IP packet from %s to %s !n",source_ip,dest_ip);

   //以下是将嗅探到的包发送到真正的目的地:

   if (lpIphdr->m_protocol ==6) //TCP
   {
           lpIphdr->m_dIP = inet_addr("192.168.0.32");

           ip_total_len = ntohs(lpIphdr->m_tlen);
           ip_header_len = (lpIphdr->m_ver_hlen)&0x0f;
       ip_header_len = ip_header_len*4;
           pTcpHeader = (TCP_HEADER *)(((char *)lpIphdr) + ip_header_len);
           tcp_head_len = (pTcpHeader->lenres)>>4;
       tcp_head_len = tcp_head_len *4;

           printf("ip_total_len= %d ip_header_len=%d tcp_head_len=%dn ", ip_total_len,ip_header_len,tcp_head_len);

          

           t =libnet_build_tcp_options(
                   (char *)(pTcpHeader) + LIBNET_TCP_H,
                   tcp_head_len - LIBNET_TCP_H,
                   l,
                   0);
         
           p_data = NULL;
           if(ip_total_len > (ip_header_len + tcp_head_len))
          p_data = (char *)(pTcpHeader) + tcp_head_len;

          
           t = libnet_build_tcp(
        ntohs(pTcpHeader->src_port),                                    /* source port */
        ntohs(pTcpHeader->dest_port),                                    /* destination port */
        ntohl(pTcpHeader->seq),                                 /* sequence number */
        ntohl(pTcpHeader->ack),                                 /* acknowledgement num */
                pTcpHeader->flag,                                     /* control flags */
        ntohs(pTcpHeader->windows),                                      /* window size */
                   0,                                          /* checksum */
        ntohs(pTcpHeader->urgent),                                          /* urgent pointer */
                ip_total_len - ip_header_len,              /* TCP packet size */
                p_data,                                                      /* payload */
                ip_total_len - ip_header_len - tcp_head_len,                              /* payload size */
                l,                                          /* libnet handle */
                0);                                         /* libnet id */

           libnet_build_ipv4_options(
                   (char *)(lpIphdr) + LIBNET_IP_H,
                   ip_header_len - LIBNET_IP_H,
                   l,
                   0);

           t = libnet_build_ipv4(
         ip_total_len,/* length */
        lpIphdr->m_tos,                                          /* TOS */
         ntohs(lpIphdr->m_ident),                                   /* IP ID */
         ntohs(lpIphdr->m_flag_frag),                                          /* IP Frag */
         lpIphdr->m_ttl,                                         /* TTL */
        IPPROTO_TCP,                                /* protocol */
        0,                                          /* checksum */
                libnet_name2addr4(l, source_ip, LIBNET_DONT_RESOLVE),         /* source IP */
                libnet_name2addr4(l, "192.168.0.32", LIBNET_DONT_RESOLVE),            /* destination IP */
                   NULL,                                       /* payload */
                   0,                                          /* payload size */
                   l,                                          /* libnet handle */
                   0);                                         /* libnet id */

           t = libnet_build_ethernet(
                   lpEthdr->eh_dst,                                   /* ethernet destination */
                   lpEthdr->eh_src,                                   /* ethernet source */
                   ETHERTYPE_IP,                               /* protocol type */
                   NULL,                                       /* payload */
                   0,                                          /* payload size */
                   l,                                          /* libnet handle */
                   0);                                         /* libnet id */
       
          
           c = libnet_write(l);
          
   }
  }
}

int main (int argc, char* argv[])
{
        /*the printer running when packet have captured*/
      

        /*the error code buf of libpcap*/
        char ebuf[PCAP_ERRBUF_SIZE];
                struct bpf_program fcode;
                bpf_u_int32 net;
                bpf_u_int32 mask; /* 所在网络的掩码 */
                char errbuf[LIBNET_ERRBUF_SIZE];

//                pcap_lookupnet("eth0", &net, &mask, ebuf);

        /*create capture handler of libpcap*/
        pcap_t *pd = pcap_open_live ("eth0", 1024, 1, 0, ebuf);

//                if (pcap_compile(pd, &fcode, MY_FILTER, 1, mask)<0)
/*                if (pcap_compile(pd, &fcode, NULL, 1, 0)<0)
                        printf(" pcap_compile error n");

                if (pcap_setfilter(pd, &fcode)<0)
            printf(" pcap_setfilter error n");*/

                l = libnet_init(
                        LIBNET_LINK,                            /* injection type */
                        NULL,                                   /* network interface */
                        errbuf);                                /* error buffer */
               
                if (l == NULL)
                {
                        printf("libnet_init() failed: %s", errbuf);
                        return 0;
                }

        /*start the loop of capture, enter printer when capted*/
        pcap_loop (pd, -1, DecodeEthPkt, NULL);

        pcap_close (pd);

        return 0;
}

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文