⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet_gen.c

📁 一个使用raw socket 构造数据包的实例
💻 C
📖 第 1 页 / 共 2 页
字号:
    return PACKET_OK;       
}        


/**********************************************************************
* 函数名称:udpcrcCheck
* 功能描述:判断收到的ip报文的udp校验和是否正确
* 输入参数:
  ipHdr    收到报文的ip头
*  输出参数:无
* 返 回 值:
    校验和正确
    校验和错误
* 其它说明:无
* 修改日期      版本号  修改人      修改内容
* ---------------------------------------------------------------------
* 2007/12/11             丁鹏              创建
************************************************************************/
int udpcrcCheck(struct ip *ipHdr)            
{
    unsigned short crcPacket;
    unsigned short crcCheck;
    unsigned short packet_ip_sum;
    unsigned char packet_ip_ttl;
    unsigned char packet_ip_p;
    unsigned short *pcrckBufBegin;
    
    struct udphdr  udpHdr;
    
    udpHdr = (struct udphdr *)(ipHdr + IP_HDR_LEN);
            
    packet_ip_ttl =  ipHdr->ip_ttl;           /* 8bit */
    packet_ip_p   =  ipHdr->ip_p;                /*  8bit */
    packet_ip_sum =  ntohs(udpHdr->uh_ulen);          /* 16bit  check crc */
    crcPacket     =  ntohs(udpHdr->uh_sum);
            
    printf("udpHdr->uh_ulen:%x", ntohs(udpHdr->uh_ulen));
            
    /* 伪首部初始化 */
    ipHdr->ip_ttl = 0;                          /* 8bit */
    ipHdr->ip_p   = IPPROTO_UDP;                /*  8bit */
    ipHdr->ip_sum =  ntohs(udpHdr->uh_ulen);    /* 16bit  check crc */
    ipHdr->ip_src.s_addr = inet_addr("10.16.8.51"); /* 32bit */
    ipHdr->ip_dst.s_addr = inet_addr("10.16.8.54"); /* 32bit */
            
    udpHdr->uh_sum = 0;
    pcrckBufBegin   = (unsigned short *)(&ipHdr->ip_ttl);
            
    crcCheck = checksum(pcrckBufBegin, ntohs(udpHdr->uh_ulen));
            
    if(crcCheck != crcPacket)
    {
        printf("udp crc wrong:packet(%x), (receive %x)---\n", crcPacket, crcCheck);
        return ERR_UDP_CRC_WRONG;
    }
    else
    {
        printf("udp crc :packet(%x), (receive %x)---\n", crcPacket, crcCheck);
    }
    return PACKET_OK;
}

/**********************************************************************
* 函数名称:packetSend
* 功能描述:发送报文
* 输入参数:
  len     发送报文长度
  pktBuf  发送报文的地址,包括eth,ip,udp头
  ptoaddr 发送的地址
*  输出参数:无
* 返 回 值:
    发送成功
    发送失败    
* 其它说明:无
* 修改日期      版本号  修改人      修改内容
* ---------------------------------------------------------------------
* 2007/12/11             丁鹏              创建
************************************************************************/
int packetSend(unsigned int len, unsigned char *pktBuf, struct sockaddr_ll *ptoaddr)
{
    int sendLen = 0;
    int ret     = 0;    
    unsigned char *pSendBuf;
    
    if(NULL == pktBuf || len == 0)
    {
        return ERR_PACKET_SEND;
    } 
    pSendBuf =  pktBuf;
    sendLen  =  len;
    while(sendLen > 0)
    {
        ret = sendto(sockfd, pSendBuf, sendLen, 0, (struct sockaddr *)ptoaddr, sizeof(ptoaddr));
        if(ret < 0)
        {
            perror("sendto err");
            return ERR_PACKET_SEND;
        }
        else
        {
            sendLen -= ret;
            pSendBuf += ret;
        }
    }
    return PACKET_SEND_OK;
}                

/**********************************************************************
* 函数名称:packetBuild
* 功能描述:构造发送到外网去的数据包
* 输入参数:
  fib_addr     转发规则,用来判断要发到哪些外网口
  cmsgDatabuf  构造报文所存放的地址
  localIp      本地ip,字符串形式
  sport        发送源端口
  dport        发送目的端口
*  输出参数:
* 返 回 值:
    构造成功
    构造失败    
* 其它说明:无
* 修改日期      版本号  修改人      修改内容
* ---------------------------------------------------------------------
* 2007/12/11             丁鹏              创建
************************************************************************/
int packetBuild(struct fib_address *fib_addr, unsigned char *cmsgDatabuf, unsigned char *localIp, unsigned short sport, unsigned short dport)
{
    unsigned char *pktBuf;
    unsigned char *puicrckBufBegin;
    struct udphdr *udpHdr;
    struct ethhdr *ethHdr;
    unsigned char dstMac[ETH_ALEN+1]={0};
    unsigned char srcMac[ETH_ALEN+1]={0};
     
    if((NULL == fib_addr_next) || (NULL == cmsgDatabuf))
    {
        printf("packetBuild: arg err\n");
        return ERR_GENERR;
    }
    /* build send packet */
    /* build udphdr */
    pktBuf = (unsigned char *)cmsgDatabuf;
    udpHdr = (struct udphdr *)(pktBuf + uiEthHdrLen + uiIpHdrLen);
    UdpHdrGen(udpHdr, dport, sport, msgDataLen);
    /* builde iphdr */       
    psDstAddr = inet_ntoa(fib_addr->ip_dst);
    psSrcAddr = LocalIp;
    ipHdr = (struct ip *)(pktBuf + sizeof(struct ethhdr));
    ipHdr->ip_ttl = 0;                        /* 8bit */
    ipHdr->ip_p = IPPROTO_UDP;                /*  8bit */
    ipHdr->ip_sum = udpHdr->uh_ulen;           /* 16bit  check crc */
    ipHdr->ip_src.s_addr = inet_addr(psSrcAddr); /* 32bit */
    ipHdr->ip_dst.s_addr = inet_addr(psDstAddr); /* 32bit */
    
    
    puicrckBufBegin = (unsigned short *)&(ipHdr->ip_ttl);
    udpHdr->uh_sum  = checksum(puicrckBufBegin, msgDataLen + FAKE_IP_HEAD + 8);
    if (0 == udpHdr->uh_sum) 
    {
        udpHdr->uh_sum = 0xffff;
    }
    IpHdrGen(ipHdr, psDstAddr, psSrcAddr, msgDataLen, IPPROTO_UDP);
              
    /* build ethhdr */
    ret = getMac(psDstAddr, dstMac);
    if(ret == 0)
    {
        printf("no %s mac , err\n", dstMac);
        return ERR_GENERR;
    }
    printf("dst ret:%d\n",ret);
    dstMac[ETH_ALEN+1]='\0';
    ret = getMac(psSrcAddr, srcMac);
    if(ret == 0)
    {
        printf("no %s mac , err\n", srcMac);
        return ERR_GENERR;
    }
    srcMac[ETH_ALEN+1]='\0';
    psrcMac=&srcMac[0];
    pdstMac=&dstMac[0];
    
    ethHdr = (struct ethhdr *)pktBuf;
    ethHdrGen(ethHdr, dstMac, srcMac);
}


/**********************************************************************
* 函数名称:Handle_Externel
* 功能描述:处理对应外网规则的数据包
* 输入参数:
  pfib_rule     转发规则,用来判断要发到哪些外网口
  cmsgDatabuf   发送报文所存放的地址
  ptoaddr      发送的地址
  msgLen        发送消息体长度 包括eth,ip,udp头
*  输出参数:
* 返 回 值:
    处理成功
    处理失败    
* 其它说明:无
* 修改日期      版本号  修改人      修改内容
* ---------------------------------------------------------------------
* 2007/12/11             丁鹏              创建
************************************************************************/
int Handle_Externel(FIB_RULE  *pfib_rule, unsigned char *cmsgDatabuf, struct sockaddr_ll *ptoaddr, unsigned int msgLen)
{
    struct fib_address *fib_addr_next;
    if((NULL == pfib_rule) || (NULL == cmsgDatabuf))
    {
        printf("Handle_Externel: arg err\n");
        return ERR_GENERR;
    }
    
    /* 遍历发送的目的地 */
    fib_addr_next = pfib_rule->pdstaddr;
    while(fib_addr_next != NULL)             
    {  
        /* build send packet */
        if(packetBuild(fib_addr_next, cmsgDatabuf, localIp, 100000, 10001) < 0)
        {
            continue;
        }
        /* send to the paket*/
        memset(&toaddr,0,sizeof(toaddr));
        ptoaddr->sll_family   = AF_PACKET;
        ptoaddr->sll_ifindex  = ifr.ifr_ifindex;  
        ptoaddr->sll_protocol = htons(ETH_P_ALL);
        ptoaddr->sll_halen   = 6;
         
        ptoaddr->sll_addr[0] = 0x00;
        ptoaddr->sll_addr[1] = 0x15;
        ptoaddr->sll_addr[2] = 0x58;
        ptoaddr->sll_addr[3] = 0x12;
        ptoaddr->sll_addr[4] = 0x9E;
        ptoaddr->sll_addr[5] = 0x5E;
           
        if(packetSend(msgLen, cmsgDatabuf, ptoaddr) < 0)
        {
           continue;
        }
        fib_addr_next = fib_addr_next->next;
    }    /*end while  */
    return PACKET_OK;      
}     




/**********************************************************************
* 函数名称:Handle_Internel
* 功能描述:处理对应外网规则的数据包
* 输入参数:
  pfib_rule     转发规则,用来判断要发到哪些内网口
  udpHdr       内网口只需处理udp头及udp负荷
*  输出参数:
* 返 回 值:
    处理成功
    处理失败    
* 其它说明:无
* 修改日期      版本号  修改人      修改内容
* ---------------------------------------------------------------------
* 2007/12/11             丁鹏              创建
************************************************************************/
int Handle_Internel(FIB_RULE  *pfib_rule, struct udphdr *udpHdr)
{
    struct fib_address *fib_addr_next;
    unsigned char       filename[20];
    int    fd;

    memset(filename, 0x00, 20)
    /* 遍历发送的目的地 */
    fib_addr_next = pfib_rule->pdstaddr;
    while(fib_addr_next != NULL)             
    {  
        if(getfilename(fib_addr_next->chipnum, &filename) == 0)
        { 
            printf("no that 8360 chip \n");
            continue;
        }
        else
        { 
            fd = open(filename, O_RDWR | O_APPEND);
            udpHdr = (struct udphdr *)pktBuf;
            /*write file */
            write(fd, udpHdr, ntohs(udpHdr->uh_ulen));
            close(fd);
        } /*end getfile name */
        fib_addr_next = fib_addr_next->next;
    }/* end while  */
    return PACKET_OK;  
}    
            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -