请问在Winpcap中如何填充ethernet头中对端和本端的MAC地址呀?
我在内网中可以获取到对端的MAC地址,但如果在外网中怎么办?比如我想给sina发送一个TCP包,需要怎么填充ethernet头呀?
救急,非常感谢!

解决方案 »

  1.   

    下面是发送ARP协议的请求包,你仔细看看吧int getmine() //发送ARP Request(请求包)数据报,请求获得本地主机的mac地址;
    {
        char   sendbuf[1024];
        int    k;
        ETHDR  eth;
        ARPHDR arp;    for(k = 0; k < 6; k++) // 生成网卡的源MAC地址和目的MAC地址
        {
            eth.eh_dst[k] = 0xff;  // 针对以太网地址
            eth.eh_src[k] = 0x82;
            arp.arp_sha[k] = 0x82; // 针对ARP中的网卡地址
            arp.arp_tha[k] = 0x00;
        }

        eth.eh_type = htons(ETH_ARP);    // 设置相应的协议
        arp.arp_hdr = htons(ARP_HARDWARE);
        arp.arp_pro = htons(ETH_IP);
        arp.arp_hln = 6;
        arp.arp_pln = 4;
        arp.arp_opt = htons(ARP_REQUEST);
        arp.arp_tpa = htonl(myip);      // 指向自己的IP地址
        arp.arp_spa = inet_addr("112.112.112.112");  // 随便写个源地址    memset(sendbuf, 0, sizeof(sendbuf)); // 转移数据,组建ARP包,准备发送
        memcpy(sendbuf, &eth, sizeof(eth));
        memcpy(sendbuf + sizeof(eth), &arp, sizeof(arp));    PacketInitPacket(lppackets, sendbuf, sizeof(eth) + sizeof(arp)); // 在驱动缓冲中保存ARP包
        if(PacketSendPacket(lpadapter,lppackets,TRUE) == FALSE) // 发送缓存的ARP包
        {
            printf("PacketSendPacket in getmine Error: %d\n", GetLastError());
            return -1;
        }
        return 0;
    }
      

  2.   

    当然还有参数(句柄)需要在其它地方获得adapterlength = sizeof(adaptername);    if(PacketGetAdapterNames((char *)adaptername, &adapterlength) == FALSE)  // 获得网卡名称
        {
            printf("PacketGetAdapterNames Error: %d\n", GetLastError());
            return -1;
        }lpadapter = PacketOpenAdapter(adapterlist[open - 1]);  // 打开相应网卡    if(!lpadapter || (lpadapter->hFile == INVALID_HANDLE_VALUE))
        {
            printf("PacketOpenAdapter Error: %d\n", GetLastError());
            return -1;
        }    if(PacketGetNetType(lpadapter, &ntype)) // 获得网卡类型及句柄
        {
            printf("\n\t\t*** Host Information ***\n");
            printf("[LinkTpye:]\t%d\t\t", ntype.LinkType);
            printf("[LinkSpeed:]\t%d b/s\n", ntype.LinkSpeed);
        }if((lppackets = PacketAllocatePacket()) == FALSE)   // 获得包句柄
        {
            printf("PacketAllocatePacket send Error: %d\n", GetLastError());
            return -1;
        }以上是程序片段,你仔细看看,或者上网搜一下syn flood程序
      

  3.   

    你发送到sina,ip地址填写sina的ip地址,mac地址填写网关的mac地址即可。
    mac地址在网关之间传输时是不断变化的,等于下一跳网关的mac地址
      

  4.   

    ip地址不会变,mac地址会发生变化
      

  5.   

    ADSL拨号时是没有网关的,网关就是本机。
    那样不是成自己发给自己了!这点好像和局域网不一样。
    我的程序在局域网中运行也是正常的,填写的就是网关的MAC,但在ADSL环境中怎么办?
      

  6.   

    ADSL有一个外网地址的啊
    通过内网和外网地址
      

  7.   

    是的,ADSL建立后会分配一个动态的公网地址,但关键是在Winpcap中需要填充ethernet头,其中需要对端和本端的MAC地址,怎么填充呀?
      

  8.   

    ADSL猫有一个Mac地址,你网卡有一个Mac地址
      

  9.   

    本端MAC使用哪个呀?
    对端MAC又使用哪个呀?
      

  10.   

    本端用网卡的,对端用Modem的
      

  11.   

    目的ip是不会变的。mac地址才是广播局域网的网关活着路由器!这跳的机器mac地址!最终才会是目的ip机器的地址
      

  12.   

    最后的老兄说的对,我研究几天终于得到这个结论。
    但关键是如何填充这个“这跳的机器mac地址”??
    请各位帮帮忙!
      

  13.   

    我是利用这种方法手动填写封包的方法发送以太网封包的.你可以参照TCP/IP协议去构造自己的封包。 u_char packet[42];
     
      
        /* 获得网卡的列表 */
        if (pcap_findalldevs(&alldevs, errbuf) == -1)
        {
            fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
            exit(1);
        }
        
        /* 打印网卡信息 */
        for(d=alldevs; d; d=d->next)
        { printf("%d. %s", ++i, d->name,"(%s)\n");  }
        
        if(i==0)
        {
            printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
            return -1;
        }
        
        inum=1;//设第一个网卡去发送封包//
          
        /* 找到要选择的网卡结构 */
        for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
        
        /* 打开选择的网卡 */
        if ( (fp = pcap_open_live(d->name, // 设备名称
                                 65536,     // portion of the packet to capture. 
                                 // 65536 grants that the whole packet will be captured on all the MACs.
                                 0,         // 如果是 1就是混杂模式
                                 1000,      // 读超时为1秒
                                 errbuf     // error buffer
                                 ) ) == NULL)
        {
            fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n");
            pcap_freealldevs(alldevs);      /* Free the device list */
            return -1;
        } printf("\nSend...........by %s\n", d->description);                             /* 假设网络环境为ethernet,我门把目的MAC设为1:1:1:1:1:1*/
        packet[0]=0xFF;
        packet[1]=0XFF;
        packet[2]=0XFF;
        packet[3]=0XFF;
        packet[4]=0XFF;
        packet[5]=0XFF;
        
                                     /* 假设源MAC为 2:2:2:2:2:2 */
        packet[6]=0x00;
        packet[7]=0x06;
        packet[8]=0x4d;
        packet[9]=0xd8;
        packet[10]=0x05;
        packet[11]=0xc6;..........
    ........... {pcap_sendpacket( fp,    //开始发送包....   
     packet,
     42);
     Sleep(40000);}
      

  14.   

    你装一个Sniffer软件,抓两个封包研究一下就知道该如何填写了,我一般用IRIS抓包的。
      

  15.   

    我早就抓包分析过了,无论目的地址是什么,里面填充的目的MAC地址都是一样的。
    但不知道这是个什么MAC地址呀?
      

  16.   

    ADSL的我就不清楚了,但我在局域网中的联外网(比方说是WWW.163.COM)时的目的MAC是网关的MAC地址,对了,你用ADSL拨号上网也应该有网关的呀,会不会你抓包的MAC地址就是网关地址? 你也可以试一下使用Tracert分析一下下一跳是哪里,
      

  17.   

    是啊,应该就是adsl modem的网关
      

  18.   

    我前面说了,在ADSL拨号时是没有网关的,网关就是本机。
    比如分配给自己的动态IP地址是111.222.222.111,那么网关地址也是111.222.222.111;
    我使用ipconfig命令或者API函数查看结果都是这样的。大家都没有遇到ADSL的情况吗?
    还有拨号上网的情况怎么办?
      

  19.   

    winpcap支持WAN不是很好(个人认为),特别是Win9x和拨号环境,
    你可以试着把这目的mac填位0看看,我记忆中某位高人说过这过是这样的,我没有试过。