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

📄 549.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 2 页
字号:
    fprintf(stdout," destination: %s " <br>

            ,ether_ntoa(eptr->ether_dhost)); <br>

  <br>

    /* check to see if we have an ip packet */ <br>

    if (ntohs (eptr->ether_type) == ETHERTYPE_IP) <br>

    { <br>

        fprintf(stdout,"(IP)"); <br>



    }else  if (ntohs (eptr->ether_type) == ETHERTYPE_ARP) <br>

    { <br>

        fprintf(stdout,"(ARP)"); <br>

    }else  if (ntohs (eptr->ether_type) == ETHERTYPE_REVARP) <br>

    { <br>

        fprintf(stdout,"(RARP)"); <br>

    }else { <br>

        fprintf(stdout,"(?)"); <br>

        exit(1); <br>

    } <br>

    fprintf(stdout,"\n"); <br>

  <br>

    return eptr->ether_type; <br>

} <br>

  <br>

You can download the full code here. <br>

Whew! Ok got that out of the way, currently we have a relatively simple framewor <br>

k to print out an ethernet header (if we want) and then handle the type. Lets st <br>

art by looking at the IP header. <br>

  <br>

IP: <br>

OK lets wip out our handy dandy RFC's (791 in this case) and take a look at what <br>



 it has to say about IP headers... here is a copy of the section which decsribes <br>

 the header. <br>

  <br>

  <br>

3.1 Internet Header Format <br>

  <br>

       A summary of the contents of the internet header follows: <br>

  <br>

           0                   1                   2                   3 <br>

           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 <br>

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

          |Version|  IHL  |Type of Service|          Total Length         | <br>

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

          |         Identification        |Flags|      Fragment Offset    | <br>

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

          |  Time to Live |    Protocol   |         Header Checksum       | <br>

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

          |                       Source Address                          | <br>

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

          |                    Destination Address                        | <br>

          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

          |                    Options                    |    Padding    | <br>



          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br>

  <br>

                           Example Internet Datagram Header <br>

  <br>

                                      Figure 4. <br>

  <br>

         Note that each tick mark represents one bit position. <br>

  <br>

Now lets peak at netinet/ip.h <br>

struct ip <br>

  { <br>

#if __BYTE_ORDER == __LITTLE_ENDIAN <br>

    unsigned int ip_hl:4;  /* header length */ <br>

    unsigned int ip_v:4;  /* version */ <br>

#endif <br>

#if __BYTE_ORDER == __BIG_ENDIAN <br>

    unsigned int ip_v:4;  /* version */ <br>

    unsigned int ip_hl:4;  /* header length */ <br>

#endif <br>

    u_int8_t ip_tos;   /* type of service */ <br>

    u_short ip_len;   /* total length */ <br>

    u_short ip_id;   /* identification */ <br>



    u_short ip_off;   /* fragment offset field */ <br>

#define IP_RF 0x8000   /* reserved fragment flag */ <br>

#define IP_DF 0x4000   /* dont fragment flag */ <br>

#define IP_MF 0x2000   /* more fragments flag */ <br>

#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */ <br>

    u_int8_t ip_ttl;   /* time to live */ <br>

    u_int8_t ip_p;   /* protocol */ <br>

    u_short ip_sum;   /* checksum */ <br>

    struct in_addr ip_src, ip_dst; /* source and dest address */ <br>

  }; <br>

  <br>

Cool, they seem to match up perfectly.... this of course would be fine to use, b <br>

ut I prefer to follow the tcpdump method of handling the version and header leng <br>

th. <br>

struct my_ip <br>

 u_int8_t ip_vhl;  /* header length, version */ <br>

#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) <br>

#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) <br>

 u_int8_t ip_tos;  /* type of service */ <br>

 u_int16_t ip_len;  /* total length */ <br>

 u_int16_t ip_id;  /* identification */ <br>

 u_int16_t ip_off;  /* fragment offset field */ <br>



#define IP_DF 0x4000   /* dont fragment flag */ <br>

#define IP_MF 0x2000   /* more fragments flag */ <br>

#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */ <br>

 u_int8_t ip_ttl;  /* time to live */ <br>

 u_int8_t ip_p;  /* protocol */ <br>

 u_int16_t ip_sum;  /* checksum */ <br>

 struct in_addr ip_src,ip_dst; /* source and dest address */ <br>

}; <br>

  <br>

Lets take a first stab at peaking into the IP header... consider the following f <br>

unction (full source here). <br>

u_char* handle_IP <br>

        (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* <br>

        packet) <br>

{ <br>

    const struct my_ip* ip; <br>

    u_int length = pkthdr-&len; <br>

    u_int hlen,off,version; <br>

    int i; <br>

  <br>

    int len; <br>

  <br>

  <br>

    /* jump pass the ethernet header */ <br>

    ip = (struct my_ip*)(packet + sizeof(struct ether_header)); <br>

    length -= sizeof(struct ether_header); <br>

  <br>

    /* check to see we have a packet of valid length */ <br>

    if (length < sizeof(struct my_ip)) <br>

    { <br>

        printf("truncated ip %d",length); <br>

        return NULL; <br>

    } <br>

  <br>

    len     = ntohs(ip->ip_len); <br>

    hlen    = IP_HL(ip); /* header length */ <br>

    version = IP_V(ip);/* ip version */ <br>

  <br>

    /* check version */ <br>

    if(version != 4) <br>

    { <br>

      fprintf(stdout,"Unknown version %d\n",version); <br>

      return NULL; <br>

    } <br>

  <br>

  <br>

    /* check header length */ <br>

    if(hlen < 5 ) <br>

    { <br>

        fprintf(stdout,"bad-hlen %d \n",hlen); <br>

    } <br>

  <br>

    /* see if we have as much packet as we should */ <br>

    if(length < len) <br>

        printf("\ntruncated IP - %d bytes missing\n",len - length); <br>

  <br>

    /* Check to see if we have the first fragment */ <br>

    off = ntohs(ip->ip_off); <br>

    if((off &apm; 0x1fff) == 0 )/* aka no 1's in first 13 bits */ <br>

    {/* print SOURCE DESTINATION hlen version len offset */ <br>

        fprintf(stdout,"IP: "); <br>

        fprintf(stdout,"%s ", <br>

                inet_ntoa(ip->ip_src)); <br>

        fprintf(stdout,"%s %d %d %d %d\n", <br>

                inet_ntoa(ip->ip_dst), <br>

                hlen,version,len,off); <br>

    } <br>

  <br>

  <br>

    return NULL; <br>

} <br>

  <br>

Given a clean arp cache this is what the output looks like on my machine, when I <br>

 try to telnet to 134.114.90.1... <br>

[root@localhost libpcap]# ./a.out 5 <br>

ETH: 0:10:a4:8b:d3:b4 ff:ff:ff:ff:ff:ff (ARP) 42 <br>

ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (ARP) 60 <br>

ETH: 0:10:a4:8b:d3:b4 0:20:78:d1:e8:1 (IP) 74 <br>

IP: 192.168.1.100 134.114.90.1 5 4 60 16384 <br>

ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (IP) 60 <br>

IP: 134.114.90.1 192.168.1.100 5 4 40 0 <br>

  <br>

Lets try and reconstruct the conversation shall we? <br>

  <br>

my computer: Who has the gateways IP (192.168.1.100)? <br>

ETH: 0:10:a4:8b:d3:b4 ff:ff:ff:ff:ff:ff (ARP) 42 <br>

gateway: I do!! <br>

ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (ARP) 60 <br>

my computer(through gateway): Hello Mr. 134.114.90.1 can we talk? <br>

ETH: 0:10:a4:8b:d3:b4 0:20:78:d1:e8:1 (IP) 74 IP: 192.168.1.100 134.114.90.1 5 4 <br>

 60 16384 <br>

 60 16384 <br>

134.114.90.1: No, piss off, I'm not listening <br>

ETH: 0:20:78:d1:e8:1 0:10:a4:8b:d3:b4 (IP) 60 IP: 134.114.90.1 192.168.1.100 5 4 <br>

 40 0 <br>

I have admittedly skipped TONS of information in a rush to provide you with code <br>

 to display the IP header (thats all you really wanted anyways wasn't it :-). Th <br>

at said, if you are lost don't worry, I will slow down and attempt to describe w <br>

hat exactly <br>

is going on. All that you really need to know up to this point is.. <br>

  <br>

All packets are sent via ethernet <br>

The ethernet header defines the protocol type of the packet it is carrying <br>

IP is one of these types (as well as ARP and RARP) <br>

The IP header is confusing as all hell <br>

So before getting too far into packet dissection it would probably benefit us to <br>

 regress a bit and talk about IP... <br>

"awww but.... that sounds boring!",you say. Well if you are really anxious I wou <br>

ld suggest you grab the tcpdump source and take a look at the following methods <br>

... :-) <br>

ether_if_print (print-ether.c) <br>

ip_print (print-ip.c) <br>

tcp_print (print-tcp.c) <br>

udp_print (print-udp.c) <br>



I've also found the sniffit source to be a great read. <br>

  <br>

*Note to self... Insert comprehensive, enlightening IP discussion here :-) :-)* <br>

  <br>

--------%< ----------------- to be continued..... <br>

-------------------------------------------------------------------------------- <br>

  <br>

[prev] [socket home ] [next] <br>

-- <br>

telnet apue.dhs.org 2323 or http://apue.dhs.org <br>

APUE:UNIX环境编程 <br>

UNP:UNIX网络编程 <br>

UKP:UNIX内核编程 <br>

BIBLE:高手传经 <br>

FTPDOC:资源共享 <br>

※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 202.114.36.176] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="537.htm">上一层</a>][<a href="550.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

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