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