]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/capture/cap_debug/tcp.c
Some refactoring.
[stg.git] / projects / stargazer / plugins / capture / cap_debug / tcp.c
1 /* $Id: tcp.c,v 1.2 2009/06/19 12:50:47 faust Exp $ 
2
3 Copyright (C) 2002 Marc Kirchner <kirchner@stud.fh-heilbronn.de>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include "libpal.h"
21 #include "types.h" /* internal types */
22
23 int
24 pkt_tcp_header(struct packet *pkt,
25                 unsigned short int sport,
26                 unsigned short int dport,
27                 unsigned int seq,
28                 unsigned int ackseq,
29                 unsigned char headerlen,
30                 unsigned char reserved,
31                 unsigned char flags,
32                 unsigned short window,
33                 unsigned short int checksum,
34                 unsigned short int urgent)
35 {
36         struct tcphdr *tcp;
37
38         if (!pkt)
39                 return EPKTINVALPTR;
40         
41         tcp = (struct tcphdr *) pkt->pkt_ptr;
42         tcp->source = htons(sport);
43         tcp->dest = htons(dport);
44         tcp->seq = htonl(seq);
45         tcp->ack_seq = htonl(ackseq);
46         tcp->window = htons(window);
47         tcp->urg_ptr = htons(urgent);
48
49         tcp->doff = headerlen;
50         tcp->res1 = reserved;
51         if (flags) {
52                 tcp->fin = ((flags & TH_FIN) != 0);
53                 tcp->syn = ((flags & TH_SYN) != 0);
54                 tcp->rst = ((flags & TH_RST) != 0);
55                 tcp->psh = ((flags & TH_RST) != 0);
56                 tcp->ack = ((flags & TH_ACK) != 0);
57                 tcp->urg = ((flags & TH_URG) != 0);
58 #  if __BYTE_ORDER == __LITTLE_ENDIAN
59                 tcp->res2 = (flags & (TH_XMAS | TH_YMAS)) >> 6;
60 #  elif __BYTE_ORDER == __BIG_ENDIAN
61                 tcp->res2 = (flags & (TH_XMAS | TH_YMAS));
62 #  else
63 #   error "Adjust your <bits/endian.h> defines"
64 #  endif
65         } else {
66                 tcp->fin = 0; 
67                 tcp->syn = 0;
68                 tcp->rst = 0;
69                 tcp->psh = 0; 
70                 tcp->ack = 0;
71                 tcp->urg = 0;
72                 tcp->res2 = 0;
73         }
74         tcp->check = htons(checksum);
75         return 0;
76 }
77
78 int
79 pkt_tcp_cksum(struct packet *pkt, char *saddr, char *daddr, 
80                 unsigned int tcp_pkt_size)
81 {
82         char *tosum;
83         struct pseudohdr *psh;
84         struct tcphdr *tcp;
85         struct in_addr addr;
86
87         if (!pkt || !saddr || !daddr)
88                 return EPKTINVALPTR;
89         
90         if ((tcp_pkt_size + pkt->pkt_pos) > pkt->pkt_size -1)
91                 return EPKTRANGE;
92         
93         if ((tosum = (char *) malloc(tcp_pkt_size+sizeof(struct pseudohdr))) != NULL) {
94                 memset(tosum, 0, tcp_pkt_size+sizeof(struct pseudohdr));
95                 psh = (struct pseudohdr *) tosum;
96                 tcp = (struct tcphdr *) pkt->pkt_ptr;
97
98                 tcp->check = 0;
99                 
100                 if (inet_pton(AF_INET, saddr, &addr) < 0)
101                         return EERRNO;
102                 psh->saddr = addr.s_addr;
103                 if (inet_pton(AF_INET, daddr, &addr) < 0)
104                         return EERRNO;
105                 psh->daddr = addr.s_addr;
106                 psh->zero = 0x00;
107                 psh->protocol = IPPROTO_TCP;
108                 psh->length = htons(tcp_pkt_size);
109                 
110                 memcpy(tosum + sizeof(struct pseudohdr), tcp, tcp_pkt_size);
111                 tcp->check = in_cksum((unsigned short *)tosum, tcp_pkt_size + sizeof(struct pseudohdr));
112                 free(tosum);
113                 return 0;
114         } else
115                 return EERRNO;
116 }
117                 
118 int
119 pkt_tcp_option(struct packet *pkt, unsigned char kind, 
120                 unsigned char len, void *optval, size_t optlen)
121 {
122         void *vp;
123         unsigned short int mss;
124
125         if (!pkt)
126                 return EPKTINVALPTR;
127         
128         if ((pkt->pkt_size) < (pkt->pkt_pos+2+optlen))
129                 return EPKTRANGE;
130         
131         vp = (void *)pkt->pkt_ptr;
132
133         memcpy(vp, &kind, 1);
134         char * p;
135         p = (char*)vp;
136         p++;
137         vp = p;
138         //vp++;
139         memcpy(vp, &len, 1);
140         //vp++;
141         p = (char*)vp;
142         p++;
143         vp = p;
144         if (kind == PKT_TCP_OPT_MSS) {
145                 mss = htons(*(unsigned short int *)optval);
146                 memcpy(vp, &mss, optlen);
147         } else if (kind ==  PKT_TCP_OPT_TIME) {
148                 unsigned int time = htonl(*(unsigned int *)optval);
149                 memcpy(vp, &time, optlen);
150         } else {
151                 memcpy(vp, optval, optlen);
152         }
153         return 0;
154 }