File: sn_packets.c

package info (click to toggle)
sniffit 0.3.5-3
  • links: PTS
  • area: non-free
  • in suites: hamm, slink
  • size: 984 kB
  • ctags: 1,367
  • sloc: ansic: 10,604; sh: 1,568; yacc: 234; lex: 202; makefile: 154
file content (109 lines) | stat: -rw-r--r-- 3,207 bytes parent folder | download
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
/* Sniffit Packet Discription File                                        */
/*   - by: Brecht Claerhout                            */

#include "sn_config.h"
#include "sn_defines.h"
#include "sn_structs.h"
#include <netinet/in.h>

extern int PROTO_HEAD;
extern char NO_CHKSUM;

/* This routine stolen from ping.c */
unsigned short in_cksum(unsigned short *addr,int len)
{
register int nleft = len;   /* leave this alone.. my opinion is that the   */
register unsigned short *w = addr; 
                            /* register is needed to make it work for both */ 
register int sum = 0;       /* BIG and LITTLE endian machines              */ 
unsigned short answer = 0;     
                        /* but then again, who am I to make such statement */

while (nleft > 1)
        {
        sum += *w++;
        nleft -= 2;
        }
if (nleft == 1)
        {
        *(unsigned char *)(&answer) = *(unsigned char *)w ;
        sum += answer;
        }
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}

int unwrap_packet (unsigned char *sp, struct unwrap *unwrapped) 
{ 
	struct IP_header  IPhead;
	struct TCP_header TCPhead;
	struct ICMP_header ICMPhead;
	struct UDP_header UDPhead;

	int i;

	memcpy(&IPhead,(sp+PROTO_HEAD),sizeof(struct IP_header));
                                                  /* IP header Conversion */
 	unwrapped->IP_len = (IPhead.verlen & 0xF) << 2;
	
	unwrapped->TCP_len = 0;         	/* Reset structure NEEDED!!! */
	unwrapped->UDP_len = 0;
	unwrapped->DATA_len = 0;
        
	if(NO_CHKSUM == 0)
		{
		sp[PROTO_HEAD+10]=0;       /* reset checksum to zero, Q&D way*/
		sp[PROTO_HEAD+11]=0;             
		if(in_cksum((sp+PROTO_HEAD),unwrapped->IP_len) != IPhead.checksum)
			{
#ifdef DEBUG_ONSCREEN
			printf("Packet dropped... (invalid IP chksum)\n");
			printf("%X   %X (len %d)\n",in_cksum((sp+PROTO_HEAD),unwrapped->IP_len),IPhead.checksum,unwrapped->IP_len);
#endif
			return NO_IP;
			}
		if(0)
			{
#ifdef DEBUG_ONSCREEN
			printf("Packet dropped... (invalid IP version)\n");
#endif
			return NO_IP_4;
			}
		memcpy((sp+PROTO_HEAD),&IPhead,sizeof(struct IP_header));
					/* restore orig buffer      */
        			 	/* general programming rule */
		}
	if(IPhead.protocol == TCP )		             /* TCP */
		{
		memcpy(&TCPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)),
						sizeof(struct TCP_header));
		unwrapped->TCP_len = ntohs(TCPhead.offset_flag) & 0xF000;
		unwrapped->TCP_len >>= 10; 
		unwrapped->DATA_len = ntohs(IPhead.length) -
				(unwrapped->IP_len) - (unwrapped->TCP_len); 
		return TCP;
		}
	if(IPhead.protocol == ICMP )		             /* ICMP */
		{
		memcpy(&ICMPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)),
						sizeof(struct ICMP_header));
		unwrapped->ICMP_len = ICMP_HEADLENGTH;
		unwrapped->DATA_len = ntohs(IPhead.length) -
				(unwrapped->IP_len) - (unwrapped->ICMP_len); 
		return ICMP; 
		}
	if(IPhead.protocol == UDP )		               /* UDP */
		{
		memcpy(&UDPhead,(sp+PROTO_HEAD+(unwrapped->IP_len)),
						sizeof(struct UDP_header));
		unwrapped->UDP_len = UDP_HEADLENGTH;
		unwrapped->DATA_len = ntohs(IPhead.length) -
				(unwrapped->IP_len) - (unwrapped->UDP_len); 
		return UDP; 
		}
	return -1; 
}