Unix Programming - payload tcp problem

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > May 2005 > payload tcp problem





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author payload tcp problem
Jnimo

2005-05-16, 5:52 pm

hi, first i want to say that english is not my first language, so
excuse me if i screw up (i talk Spanish)

i am doing a sniffer (kinda lame, but i need to learn how to use the
pcap library), but i have a problem in the code (well not in the code
because i can compile and run the program but no too well)

i put the code here please read:

/ ****************************************
****************************************

# snifer v1.0
#

Base de un sniffer
Requiere pcap
jimmy

use: 'gcc sniffer2.c -o salida -pcap'
****************************************
****************************************
/

#define __FAVOR_BSD

#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sysexits.h>
/* capa 2 */
#include <net/ethernet.h>
/* capa 3 */
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <net/if_arp.h>

/* capa 4 */
#include "tcp.h"
#include "udp.h"
#include <netinet/ip_icmp.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include "sniffer.h"

u_char *payload; /* payload */
u_char *payload2;

int
main (int argc, char *argv[])
{
char *dev; //el dispositivo
char errbuf[PCAP_ERRBUF_SIZE]; //el error
pcap_t *descr; //la conexion
u_char* args=NULL;
dev=pcap_lookupdev(errbuf);
if(dev==NULL)
{
printf("Error abriendo interface: %s\n",errbuf);
exit(1);
}
descr=pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
if(descr==NULL)
{
printf("error abriendo conexion: %s\n",errbuf);
exit(1);
}
while(1) //creo la conexion
{
pcap_loop(descr,1,do_pcap,NULL);
}
return 0;
}

//funcion para pasar al pcap_loop pkt tiene el paquete, hdr tiene la
informacion de llegada del paquete
void do_pcap(u_char * udata, const struct pcap_pkthdr * hdr, const
u_char * pkt)
{

if (hdr->caplen < ETHER_HDR_LEN)
{
printf("error paquete con tamano menor al que deberia");
return;
}
int size_ethernet = sizeof(struct ether_header);
int size_ip = sizeof(struct ip);
int size_tcp = sizeof(struct tcphdr);
int size_udp=sizeof(struct udphdr);

// payload2 = (u_char *)(pkt + size_ethernet + size_ip + size_udp);*/

printf("paquete!!!!\n");
printf("Tiempo: %d %d\n",hdr->ts.tv_sec,hdr->ts.tv_usec);
do_ethernet(pkt, hdr->caplen);
payload = (u_char *)(pkt + size_ethernet + size_ip + size_tcp);//HERE
IS THE PROBLEM
printf("%s\n",payload); //HERE IS THE PROBLEM
}

int do_ethernet(const u_char * pkt, int length)
{
char buffer[PCAP_SNAPLEN];
struct ether_header *eth =(void*) pkt;
u_char *ptr; int i;
u_short ether_type;
ether_type=ntohs(eth->ether_type);
int size_ethernet=sizeof(struct ether_header);
int size_ip=sizeof(struct ip);
int size_tcp=sizeof(struct tcphdr);
payload = (u_char *)(pkt + size_ethernet + size_ip + size_tcp);
if(ether_type==ETHERTYPE_ARP)
{
printf("CAPA 3 ARP");
do_arp((struct arphdr*)buffer,length-ETHER_HDR_LEN);
return 0;
}
if(ether_type==ETHERTYPE_REVARP)
{
printf("CAPA 3 RARP");
do_arp((struct arphdr*)buffer,length-ETHER_HDR_LEN);
return 0;
}
memcpy(buffer, pkt + ETHER_HDR_LEN, length - ETHER_HDR_LEN);

printf("CAPA 2 -> TAMANO %d: ", length);
printf(" Fuente MAC:");
ptr = eth->ether_shost; i = ETHER_ADDR_LEN;
do{
printf("%s%x", (i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
}while(--i>0);
ptr = eth->ether_dhost; i = ETHER_ADDR_LEN;
printf("\t Destino MAC:");
do{
printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
}while(--i>0);
printf(" tipo:0x %x\n", ntohs(eth->ether_type));

return do_ip((struct ip*)buffer, length - ETHER_HDR_LEN,pkt);

}

//funcion para que ejecute si es ip
int do_ip(const struct ip * ip, int length, const u_char * pkt)
{
char buffer[PCAP_SNAPLEN];
int offset = ip->ip_hl << 2;
char* p;
printf("capa 3 -> IPv %d ", ip->ip_v);
printf("Fuente IP %s ", inet_ntoa(ip->ip_src));
printf("Destino IP %s ", inet_ntoa(ip->ip_dst));
printf("protocolo %d\n", ip->ip_p);

memcpy(buffer, (void*)ip + offset, length - offset);

switch(ip->ip_p) {
case IPPROTO_TCP:
do_tcp((struct tcphdr*)buffer, length - offset);
break;
case IPPROTO_UDP:
do_udp((struct udphdr*)buffer, length - offset);
break;
case IPPROTO_ICMP:
do_icmp((struct icmp*)buffer, length - offset);
break;
default:
return 0;
}
return 1;
}

//funcion para que ejecute si es tcp
int do_tcp(const struct tcphdr * tcp, int length)
{
u_char flags;
printf("CAPA 4 TCP-> puerto fuente:%d puerto destino:%d sequencia:
0x%x ack: 0x%x flags:", htons(tcp->th_sport), htons(tcp->th_dport),
ntohl(tcp->th_seq), ntohl(tcp->th_ack));

if ((flags = tcp->th_flags) &
(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_
URG|TH_ECE|TH_CWR)) {
if (flags & TH_FIN) printf(" FIN");
if (flags & TH_SYN) printf(" SYN");
if (flags & TH_RST) printf(" RST");
if (flags & TH_PUSH) printf(" PUSH");
if (flags & TH_ACK) printf(" ACK");
if (flags & TH_URG) printf(" URG");
if (flags & TH_ECE) printf(" ECE");
if (flags & TH_CWR) printf(" CWR");
}
printf("\n\nTamano: Payload %s\n\n",payload);
return 1;
}

//funcion para que ejecute si es udp
int do_udp(const struct udphdr * udp, int length)
{
printf("CAPA 4 UDP-> puerto fuente:%d puerto destino: %d\n\n",
htons(udp->uh_sport), htons(udp->uh_dport));
return 1;
}

//funcion para que ejecute si es icmp
int do_icmp(const struct icmp * icmp, int length)
{
printf("CAPA 4 ICMP-> tipo %d codigo %d\n\n", icmp->icmp_type,
icmp->icmp_code);
return 1;
}

int do_arp(const struct arphdr *arp,int length)
{
printf("-> ar_hrd:%d ar_pro %d",arp->ar_hrd,arp->ar_pro);
return 1;
}

well, kinda lame and noob, but i am started with this library, if u see
in the function do_pcap is a printf of the payload, in theory that
print the info of the package, but he only print garbage

i put the library tcp.h and udp.h if that have someting of valor

tcp.h



#ifndef _NETINET_TCP_H
#define _NETINET_TCP_H 1

#include <features.h>

/*
* User-settable options (used with setsockopt).
*/
#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */
#define TCP_MAXSEG 2 /* Set maximum segment size */
#define TCP_CORK 3 /* Control sending of partial frames */
#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
#define TCP_KEEPINTVL 5 /* Interval between keepalives */
#define TCP_KEEPCNT 6 /* Number of keepalives before death */
#define TCP_SYNCNT 7 /* Number of SYN retransmits */
#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
#define TCP_INFO 11 /* Information about this connection. */
#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */

#ifdef __USE_MISC
# include <sys/types.h>


typedef u_int32_t tcp_seq;
/*
* TCP header.
* Per RFC 793, September, 1981.
*/
struct tcphdr
{
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
# if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t th_x2:4; /* (unused) */
u_int8_t th_off:4; /* data offset */
# endif
# if __BYTE_ORDER == __BIG_ENDIAN
u_int8_t th_off:4; /* data offset */
u_int8_t th_x2:4; /* (unused) */
# endif
u_int8_t th_flags;
# define TH_FIN 0x01
# define TH_SYN 0x02
# define TH_RST 0x04
# define TH_PUSH 0x08
# define TH_ACK 0x10
# define TH_URG 0x20
# define TH_ECE 0x40
# define TH_CWR 0x80
u_int16_t th_win; /* window */
u_int16_t th_sum; /* checksum */
u_int16_t th_urp; /* urgent pointer */
};


enum
{
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING /* now a valid state */
};

# define TCPOPT_EOL 0
# define TCPOPT_NOP 1
# define TCPOPT_MAXSEG 2
# define TCPOLEN_MAXSEG 4
# define TCPOPT_WINDOW 3
# define TCPOLEN_WINDOW 3
# define TCPOPT_SACK_PERMITTED 4 /* Experimental */
# define TCPOLEN_SACK_PERMITTED 2
# define TCPOPT_SACK 5 /* Experimental */
# define TCPOPT_TIMESTAMP 8
# define TCPOLEN_TIMESTAMP 10
# define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2
) /* appendix A */

# define TCPOPT_TSTAMP_HDR \

(TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)

/*
* Default maximum segment size for TCP.
* With an IP MSS of 576, this is 536,
* but 512 is probably more convenient.
* This should be defined as MIN(512, IP_MSS - sizeof (struct
tcpiphdr)).
*/
# define TCP_MSS 512

# define TCP_MAXWIN 65535 /* largest value for (unscaled) window */

# define TCP_MAX_WINSHIFT 14 /* maximum window shift */

# define SOL_TCP 6 /* TCP level */


# define TCPI_OPT_TIMESTAMPS 1
# define TCPI_OPT_SACK 2
# define TCPI_OPT_WSCALE 4
# define TCPI_OPT_ECN 8

/* Values for tcpi_state. */
enum tcp_ca_state
{
TCP_CA_Open = 0,
TCP_CA_Disorder = 1,
TCP_CA_CWR = 2,
TCP_CA_Recovery = 3,
TCP_CA_Loss = 4
};

struct tcp_info
{
u_int8_t tcpi_state;
u_int8_t tcpi_ca_state;
u_int8_t tcpi_retransmits;
u_int8_t tcpi_probes;
u_int8_t tcpi_backoff;
u_int8_t tcpi_options;
u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;

u_int32_t tcpi_rto;
u_int32_t tcpi_ato;
u_int32_t tcpi_snd_mss;
u_int32_t tcpi_rcv_mss;

u_int32_t tcpi_unacked;
u_int32_t tcpi_sacked;
u_int32_t tcpi_lost;
u_int32_t tcpi_retrans;
u_int32_t tcpi_fackets;

/* Times. */
u_int32_t tcpi_last_data_sent;
u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */
u_int32_t tcpi_last_data_recv;
u_int32_t tcpi_last_ack_recv;

/* Metrics. */
u_int32_t tcpi_pmtu;
u_int32_t tcpi_rcv_ssthresh;
u_int32_t tcpi_rtt;
u_int32_t tcpi_rttvar;
u_int32_t tcpi_snd_ssthresh;
u_int32_t tcpi_snd_cwnd;
u_int32_t tcpi_advmss;
u_int32_t tcpi_reordering;
};

#endif /* Misc. */

#endif /* netinet/tcp.h */


udp.h


#ifndef __NETINET_UDP_H
#define __NETINET_UDP_H 1

#include <sys/cdefs.h>
#include <sys/types.h>

__BEGIN_DECLS

/* UDP header as specified by RFC 768, August 1980. */

struct udphdr {
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
u_int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};

#define SOL_UDP 17 /* sockopt level for UDP */

__END_DECLS

#endif /* netinet/udp.h */

please, if any1 can help me i will apreciate

Pascal Bourguignon

2005-05-16, 5:52 pm

"Jnimo" <Jimmy.nimo@gmail.com> writes:

> hi, first i want to say that english is not my first language, so
> excuse me if i screw up (i talk Spanish)
>
> i am doing a sniffer (kinda lame, but i need to learn how to use the
> pcap library), but i have a problem in the code (well not in the code
> because i can compile and run the program but no too well)
>
> i put the code here please read:
> [...]
> please, if any1 can help me i will apreciate


If you could characterize the problem you have we could help you faster.
¿Podrias decinos más acerca del problema que tienes?

--
__Pascal Bourguignon__ http://www.informatimago.com/
You're always typing.
Well, let's see you ignore my
sitting on your hands.
Pascal Bourguignon

2005-05-16, 5:52 pm

"Jnimo" <Jimmy.nimo@gmail.com> writes:

> hi, first i want to say that english is not my first language, so
> excuse me if i screw up (i talk Spanish)
>
> i am doing a sniffer (kinda lame, but i need to learn how to use the
> pcap library), but i have a problem in the code (well not in the code
> because i can compile and run the program but no too well)
>
> i put the code here please read:
> [...]
> please, if any1 can help me i will apreciate
>


Y nos hara falta sniffer.h tambien.

-*- mode: compilation; default-directory: "/local/users/pjb/src/miscellaneous/c/pcap-sniffer/" -*-
gcc sniffer2.c -o sniffer2 -lpcap
In file included from sniffer2.c:29:
tcp.h:90: error: parse error before numeric constant
sniffer2.c:37:21: sniffer.h: No such file or directory
sniffer2.c: In function `main':
sniffer2.c:63: error: `do_pcap' undeclared (first use in this function)
sniffer2.c:63: error: (Each undeclared identifier is reported only once
sniffer2.c:63: error: for each function it appears in.)
sniffer2.c: At top level:
sniffer2.c:69: error: parse error before "de"
sniffer2.c:70: error: syntax error before "void"
sniffer2.c:72: error: `do_pcap' used prior to declaration
sniffer2.c: In function `do_pcap':
sniffer2.c:90: error: `IS' undeclared (first use in this function)
sniffer2.c:90: error: parse error before "THE"
sniffer2.c: In function `do_ethernet':
sniffer2.c:96: error: `PCAP_SNAPLEN' undeclared (first use in this function)
sniffer2.c: In function `do_ip':
sniffer2.c:139: error: `PCAP_SNAPLEN' undeclared (first use in this function)
sniffer2.c:169:10: missing terminating " character
sniffer2.c:170:1: invalid suffix "x" on integer constant
sniffer2.c:170:1: invalid suffix "x" on integer constant
sniffer2.c: In function `do_tcp':
sniffer2.c:170: error: parse error before numeric constant
sniffer2.c:170:11: invalid suffix "x" on integer constant
sniffer2.c:170:22: missing terminating " character

Compilation exited abnormally with code 1 at Mon May 16 20:00:16



(Me parece que el programa shar podria ser útil para adjuntar varios
archivos fuentes en un mensaje).

--
__Pascal Bourguignon__ http://www.informatimago.com/
You're always typing.
Well, let's see you ignore my
sitting on your hands.
Jnimo

2005-05-16, 8:48 pm

sorry

sniffer.h

/ ****************************************
****************************************

#
#

see 'sniffer2.c'

****************************************
****************************************
/

#define PCAP_SNAPLEN 1518
pcap_t *pcap = NULL;

void
do_pcap(u_char *, const struct pcap_pkthdr *, const u_char *);

int
do_ethernet(const u_char *, int);

int
do_ip(const struct ip *, int);

int
do_tcp(const struct tcphdr *, int);

int
do_udp(const struct udphdr *, int);

int
do_icmp(const struct icmp *, int);

int do_arp(const struct arphdr * ip, int length);


my problem? well, in theory when i printf the payload, it have to print
the package data (no the header, but the real data), and he dont, by
example, if it a tcp html package it have to print all the data of a
package, but print only garbage

i dont have enough info about that part, the manual and tutorial only
refer to the header of the package but i need the data

mi problema? bueno segun lo q he leido y visto ese codigo deberia de
mostrarme cuando le doy imprimir el payload, el paquete como tal, la
info (si es HTML pues html, y si es ftp pues data como tal) pero solo
imprime basura

no tengo suficiente informacion hacerca de esa parte, los manuales y
tutoriales que encuentro solo se refieren a la cabezera (que eso ya
funcioona bien) pero necesito la data

si pueden ayudar, se los agradecere mucho

thanks a lot

Pascal Bourguignon

2005-05-17, 5:57 pm

"Jnimo" <Jimmy.nimo@gmail.com> writes:
> [...]
> my problem? well, in theory when i printf the payload, it have to print
> the package data (no the header, but the real data), and he dont, by
> example, if it a tcp html package it have to print all the data of a
> package, but print only garbage


It seems to me that the problem you have is that you use a constant
offset to the payload. IP headers are not fixed size. You must
compute the real payload offset from the data found in the ip header.

Of course, if it's not an IP packet, the "payload" is something else
found somewhere else. So you'd better dump the payload from the
protocol specific functions rather than from do_pcap.


Me parece que tu problema es que usas un offset fijo en lugar de tomar
en cuenta el heco que el encabezamiento IP es de tamaño variable.


Cuidado, cuando se converte entre little endian y big endian, la
transformación simetrica es la misma, pero por otros ordenes de
octetos, la transformación puede no ser simetrica. Luego, no hay que
confundir ntohs vs. htons:
htons(tcp->th_sport), htons(tcp->th_dport),
no es correcto, hay que escribir:
ntohs(tcp->th_sport), ntohs(tcp->th_dport),
(Network to Host short).


No deberias copiar el buffer. Es más simple y más rapido pasar
simplemente un puntero:
memcpy(buffer, pkt + ETHER_HDR_LEN, length - ETHER_HDR_LEN);
mejor escribir:
char* payload=pkt+ETHER_HDR_LEN;
int payload_length=length-ETHER_HDR_LEN;


Proba con este patch:

diff -Naurtwb orig/sniffer2.c src/sniffer2.c
--- orig/sniffer2.c 2005-05-17 21:00:02.000000000 +0200
+++ src/sniffer2.c 2005-05-17 21:41:39.000000000 +0200
@@ -88,11 +88,22 @@
printf("paquete!!!!\n");
printf("Tiempo: %d %d\n",hdr->ts.tv_sec,hdr->ts.tv_usec);
do_ethernet(pkt, hdr->caplen);
- payload = (u_char *)(pkt + size_ethernet + size_ip + size_tcp);//HERE
- //IS THE PROBLEM
- printf("%s\n",payload); //HERE IS THE PROBLEM
}

+void dump(const char* title,const char* buffer,int length,short ascii){
+ int i;
+ printf("Dump of %s:\n",title);
+ for(i=0;i<length;){
+ int l=i+16;
+ int j=i;
+ printf("%04x: ",i);
+ for(;(i<length)&&(i<l);i++){ printf("%02x ",(unsigned char)buffer[i]); }
+ for(;(i<l);i++){ printf(" "); }
+ if(ascii){
+ for(;(j<length)&&(j<l);j++){
+ printf("%c",isgraph(buffer[j])?buffer[j]:'_'); }}
+ printf("\n"); }}
+
int do_ethernet(const u_char * pkt, int length)
{
char buffer[PCAP_SNAPLEN];
@@ -103,7 +114,6 @@
int size_ethernet=sizeof(struct ether_header);
int size_ip=sizeof(struct ip);
int size_tcp=sizeof(struct tcphdr);
- payload = (u_char *)(pkt + size_ethernet + size_ip + size_tcp);
if(ether_type==ETHERTYPE_ARP)
{
printf("CAPA 3 ARP");
@@ -131,6 +141,8 @@
}while(--i>0);
printf(" tipo:0x %x\n", ntohs(eth->ether_type));

+ dump("Ethernet payload",buffer,length - ETHER_HDR_LEN,0);
+
return do_ip((struct ip*)buffer, length - ETHER_HDR_LEN,pkt);

}
@@ -147,6 +159,7 @@
printf("protocolo %d\n", ip->ip_p);

memcpy(buffer, (void*)ip + offset, length - offset);
+ dump("IP payload",buffer,length-offset,0);

switch(ip->ip_p) {
case IPPROTO_TCP:
@@ -182,7 +195,8 @@
if (flags & TH_ECE) printf(" ECE");
if (flags & TH_CWR) printf(" CWR");
}
- printf("\n\nTamano: Payload %s\n\n",payload);
+ dump("TCP payload",((const char*)tcp)+((tcp->th_off)<<2),
+ length-((tcp->th_off)<<2),1);
return 1;
}

@@ -191,6 +205,7 @@
{
printf("CAPA 4 UDP-> puerto fuente:%d puerto destino: %d\n\n",
htons(udp->uh_sport), htons(udp->uh_dport));
+ dump("UDP payload",((const char*)udp)+8,(ntohs(udp->uh_ulen)-8),1);
return 1;
}



--
__Pascal Bourguignon__ http://www.informatimago.com/

This is a signature virus. Add me to your signature and help me to live
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com