raw socket

Ondra Holecek bln at bln.no-ip.org
Tue Mar 9 17:27:41 CET 2004


ono, celkove (s mensimi upravami) ten kod vypada zatim takto:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <errno.h>

int posli(char *packet, int delka);
int checksum(char *data, int count);

int main(int argc, char *argv[]) {
	char *packet;
	struct ip *ipp;
	struct tcphdr *tcpp;

	packet = (char *)malloc(sizeof(struct ip) + sizeof(struct tcphdr));
	ipp = (struct ip *)packet;
	tcpp = (struct tcphdr *)(packet+sizeof(struct ip));

	ipp->ip_hl = 5;
	ipp->ip_v = 4;
	ipp->ip_tos = 16;
	ipp->ip_len = htons(40);
	ipp->ip_id = htons(20372);
	ipp->ip_off = htons(0x4000);
	ipp->ip_ttl = 64;
	ipp->ip_p = 6;
	ipp->ip_sum = 0;
	ipp->ip_src.s_addr = inet_addr("192.168.1.147");
	ipp->ip_dst.s_addr = inet_addr("192.168.1.1");

	tcpp->th_sport = htons(8989);
	tcpp->th_dport = htons(44);
	tcpp->th_seq = htonl(3925344890);
	tcpp->th_ack = htonl(0);
	tcpp->th_off = 5;
	tcpp->th_x2 = 0;
	tcpp->th_flags = TH_SYN;
	tcpp->th_win = htons(65535);
	tcpp->th_sum = 0;
	tcpp->th_urp = htons(0);


	tcpp->th_sum = htons(checksum( (char *)tcpp, sizeof(struct tcphdr) ));
	printf("tcp checksum: %d\n", ntohs(tcpp->th_sum));

	ipp->ip_sum = htons(checksum( (char *)ipp, sizeof(struct ip) ));
	printf("ip checksum: %d\n", ntohs(ipp->ip_sum));

	posli(packet, sizeof(struct ip) + sizeof(struct tcphdr));
}

int posli(char *packet, int delka) {
	int sockfd, sd, x;
	struct sockaddr_in toaddr;

	sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);

	sd = 1;
	x = setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &sd, sizeof(sd));
	printf("setsockopt: %i, sockfd: %i, errno: %i\n", x, sockfd, errno);

	bzero((char *)&toaddr, sizeof(toaddr));
	toaddr.sin_addr.s_addr = inet_addr("192.168.1.1");
	toaddr.sin_port = 0;
	toaddr.sin_family = AF_INET;
	toaddr.sin_len = sizeof(struct sockaddr_in);

	sd = sendto(sockfd, packet, delka, 0, (struct sockaddr *)&toaddr, 
sizeof(struct sockaddr));
	printf("sendto: %i, delka: %i, errno: %i\n", sd, delka, errno);
	close(sockfd);

	for (x=0; x<delka; x++) {
		printf("%02x ", *((unsigned char *)(packet+x)));
		if (x % 10 == 0 && x != 0) printf("\n");
	}
	printf("\n");
}

int checksum(char *data, int count)
{
		/* Compute Internet Checksum for "count" bytes
		*         beginning at location "addr".
		*/
	register long sum = 0;

	while( count > 1 )  {
		/*  This is the inner loop */
		sum += * (unsigned short *) data++ ;
		count -= 2;
	}

		/*  Add left-over byte, if any */
	if( count > 0 )
		sum += * (unsigned char *) data;

		/*  Fold 32-bit sum to 16 bits */
	while (sum>>16)
	sum = (sum & 0xffff) + (sum >> 16);

	return ~sum;
}


myslim ze by tam chyba zadna byt nemela, jedna se o zahajovaci packet. Ale 
porad to nefunguje a vypisuje:

tcp checksum: 22324
ip checksum: 23832
setsockopt: 0, sockfd: 3, errno: 0
sendto: -1, delka: 40, errno: 22
45 10 00 28 4f 94 40 00 40 06 5d 
18 c0 a8 01 93 c0 a8 01 01 23 
1d 00 2c e9 f8 02 7a 00 00 00 
00 50 02 ff ff 57 34 00 00 







On Tuesday 09 March 2004 02:22, Dan Lukes wrote:
> Ondra Holecek wrote:
> > mam takovy kus kodu:
> >
> > 	setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &sd, sizeof(sd));
> > 	printf("sockfd: %i, errno: %d\n", sockfd, errno);
> >
> > pokud ho prelozim a spustim na fbsd 5.1-REL, dostanu nasledujici vypis
> >
> > sockfd: 3, errno: 0
>
> 	Nejprve zacnu hubovanim - takhle to samozrejme delat nelze. setockopt,
> jako vetsina ostatnich funkci, vraci navratovou hodnotu, procemz errno
> nastavuje JEN TEHDY pokud doslo k chybe. Jinymi slovy, tady ti to
> nahodou vychazi - errno je nula. Kdyby ale nebylo - tak to neznamena, ze
> doslo k chybe - muze to taky znamenat, ze k chybe nedoslo a tak se
> hodnota errno proste nezmenila.
>
> > 	toaddr.sin_addr.s_addr = inet_addr("192.168.1.1");
> > 	toaddr.sin_port = 0;
> > 	toaddr.sin_family = AF_INET;
>
> 	Nevidim tady nikde radnou inicializaci one struktury - z uryvku bohuzel
> nelze poznat, zda je to staticka promenna (a tedy je naplnena nulou)
> nebo zda jde o automatickou promennou (a tedy je jeji inicialni obsah
> nedefinovan). Pokud neni promenna inicializovana, mela by nejprve byt -
> jinak tam budou nahodne veci. Kazdopadne bych tu jeste nekde cekal
>
> toaddr.sin_len=sizeof(toaddr)
>
> 	No - a pak muze moci za EINVAL samotny vadny paket - napriklad
> nespravna hodnota ip_vhl nebo ip_len - i to je duvod pro invaliditu paketu.
>
> 	Ktera z techto veci za EINVAL muze (a zda vubec nejaka) je uz vec,
> kterou jest treba ozkouseti ...
>
> 						Dan




More information about the Users-l mailing list