1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
/****************************************************************************
** File: ip.c
**
** Author: Mike Borella
**
** Comments: Dump IP header information
**
*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "config.h"
#include "ip.h"
#include "esp.h"
#include "ah.h"
#include "icmp.h"
#include "tcp.h"
#include "udp.h"
extern struct arg_t *my_args;
/*----------------------------------------------------------------------------
**
** in_cksum.c
**
** Do IP checksum
**
**----------------------------------------------------------------------------
*/
u_int16_t in_cksum(u_int16_t *addr, int len)
{
int nleft = len;
u_int16_t *w = addr;
u_int32_t sum = 0;
u_int16_t answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
/*
* mop up an odd byte, if necessary
*/
if (nleft == 1)
{
*(u_int8_t *)(&answer) = *(u_int8_t *)w ;
sum += answer;
}
/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
/*----------------------------------------------------------------------------
**
** dump_ip()
**
** Parse IP header and dump fields
**
**----------------------------------------------------------------------------
*/
void dump_ip(const u_char *bp, int length)
{
IPHdr *ip, ip2;
u_int hlen, len, off;
u_char *cp = NULL;
u_int frag_off;
u_char tos;
u_int16_t csum;
u_int16_t my_csum;
/*
* Dump header announcement
*/
printf("-----------------------------------------------------------------\n");
printf(" IP Header\n");
printf("-----------------------------------------------------------------\n");
/*
* View the packet as an IP header
*/
ip = (IPHdr *) bp;
/*
* Check for truncated header and truncated packet
*/
if (length < sizeof(IPHdr))
{
printf("Truncated header, length = %d bytes\n", length);
return;
}
len = ntohs(ip->ip_len);
if (length < len)
{
printf("Truncated packet: length field = %d, actual length = %d\n",
len, length);
return;
}
/*
* Dump header fields
*/
csum = ntohs(ip->ip_csum);
hlen = ip->ip_hl*4;
if (!my_args->n)
{
/* Don't print anything except src and dst addresses in minmal mode */
if (!my_args->m)
{
printf("Version: %d\n", ip->ip_v);
printf("Header length: %d\n", hlen);
tos = ip->ip_tos;
printf("Type of service: %d", tos);
printf(" (precedence=%d, D=%d, T=%d, R=%d, U=%d)\n",
tos >> 5, (tos & 0x10) >> 4, (tos & 0x08) >> 3,
(tos & 0x04) >> 2, tos & 0x03);
printf("Total length: %d\n", ntohs(ip->ip_len));
printf("Identification #: %d\n", ntohs(ip->ip_id));
frag_off = ntohs(ip->ip_off);
printf("Fragmentation offset: %d", (frag_off & 0x1fff) * 8);
frag_off &= 0xe000;
printf(" (U=%d, DF=%d, MF=%d)\n", (frag_off & 0x8000) >> 15,
(frag_off & 0x4000) >> 14, (frag_off & 0x2000) >> 13);
printf("Time to live: %d\n", ip->ip_ttl);
printf("Protocol: %d\n", ip->ip_p);
printf("Header checksum: %d ", csum);
memcpy((void *) &ip2, (void *) ip, sizeof(IPHdr));
ip2.ip_csum = 0;
my_csum = ntohs(in_cksum((u_int16_t *) &ip2, sizeof(IPHdr)));
if (my_csum != csum) printf("(error: should be %d)", my_csum);
printf("\n");
}
printf("Source address %s\n", inet_ntoa(ip->ip_src));
printf("Destination address %s\n", inet_ntoa(ip->ip_dst));
}
/*
* If this is fragment zero, hand it to the next higher
* level protocol.
*/
len -= hlen;
off = ntohs(ip->ip_off);
if ((off & 0x1fff) == 0)
{
cp = (u_char *) ip + hlen;
switch (ip->ip_p)
{
case TCP_NEXT_HEADER:
dump_tcp(cp, len);
break;
case UDP_NEXT_HEADER:
dump_udp(cp, len);
break;
case ICMP_NEXT_HEADER:
dump_icmp(cp);
break;
case IP_NEXT_HEADER:
dump_ip(cp, len);
break;
case ESP_NEXT_HEADER:
dump_esp(cp, len);
break;
case AH_NEXT_HEADER:
dump_ah(cp, len);
break;
default:
break;
}
}
}
|