/***************************************************************************
sorcery.c - for sorcery and GUI--
-------------------
begin : Tue Sep 11 2001
copyright : (C) 2001 by Josiah Zayner
email : phric@legions.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "wand.h"
void ip_sorcery(struct ip *ip_sorc,
struct in_addr source,
struct in_addr dest,
int proto,
unsigned int hl,
unsigned int ver,
unsigned char tos,
unsigned short len,
unsigned short id,
unsigned char ttl,
int off
)
{
ip_sorc->ip_hl = hl;
ip_sorc->ip_v = ver;
ip_sorc->ip_tos = tos;
ip_sorc->ip_len = len;
ip_sorc->ip_id = id;
ip_sorc->ip_ttl = ttl;
ip_sorc->ip_p = proto;
ip_sorc->ip_off = off;
ip_sorc->ip_src = source;
ip_sorc->ip_dst = dest;
}
int mix_ipoption(unsigned int opt,
unsigned int optlen,
unsigned int totlen,
struct ip *ip_p,
char *pack
)
{
static int oper;
/* optlen = x8bits we need to ocnvert to x32bits */
if(optlen % 4){ oper = (optlen / 4) + (optlen % 4); }
else { oper = (optlen / 4); }
ip_p->ip_len = totlen;
ip_p->ip_hl = 5 + oper; /* hl is in x32 bits */
memcpy(pack, ip_p, S_IP);
memcpy(pack + S_IP, &opt, (oper * 4));
return (oper * 4);
}
int packet_sorcery(char *pack,
struct extra_ingredients exi,
struct in_addr daddr,
struct in_addr saddr
)
{
static int a = 0;
for(; exi.num > a; a++)
{
if(cast_spell(pack, exi, daddr, saddr) == -1)
{
perror("sendto");
return -1;
}
}
return 0;
}
int cast_spell(char *envelope,
struct extra_ingredients exi,
struct in_addr dst,
struct in_addr src
)
{
int s, one = 1, recve, snoop, tries = 1;
char *buff = clalloc(65535);
struct sockaddr_in endup;
struct sockaddr sn;
struct looky looky;
struct timeval tim;
fd_set r;
int sizer = sizeof(struct sockaddr);
/* open a raw socket */
if((s = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
{
perror("socket");
exit(s);
}
/* set socket options at IP level, so we can create our own IP header */
if((setsockopt(s, SOL_IP, IP_HDRINCL, &one, sizeof(one))) == -1)
{
perror("setsockopt");
exit(-1);
}
/* we need to set this socket option to send and recv broadcasts
It is supposed to only be datagram broadcast but should I
enforce this and even so I need to figure a way to extract
the header values from the memory segment
*/
if(src.s_addr & 0xff000000 || dst.s_addr & 0xff000000)
{
if((setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one))) == -1)
{
perror("setsockopt");
exit(-1);
}
}
/* fill in sockaddr struct bLAH! */
memset(&endup, '\0', sizeof(struct sockaddr_in));
endup.sin_family = PF_INET;
endup.sin_port = exi.dport;
endup.sin_addr = dst;
/* send packet woohooo! */
sendto(s,
envelope,
exi.pack_sz,
0,
(struct sockaddr *)&endup,
sizeof(struct sockaddr)
);
/* right now we have no way to check if the src address is
our address so should we snoop the packet? Make sure it
doesn't snoop by default
*/
if(exi.READ_IT) {
/* open second socket for snooping them packets */
if((snoop = socket(PF_INET, SOCK_RAW, 0)) == -1)
{
perror("snoop socket");
exit(snoop);
}
memset(&looky, '\0', sizeof(struct looky));
memset(&sn,'\0', sizeof(struct sockaddr));
memset(buff,'\0', 65535);
FD_ZERO(&r);
FD_SET(snoop, &r);
tim.tv_sec = 5;
fcntl(snoop, F_SETFL, O_NONBLOCK);
while(1) {
recve = select(snoop + 1, &r, NULL, NULL, &tim);
if(FD_ISSET(snoop, &r)) break;
else tries++;
if(tries == 3)
exit(-1);
}
if(recve)
{
while(1)
{
if((recve = recvfrom(snoop, buff, 65535, 0, &sn, &sizer)) < 0)
{
switch(recve)
{
case EAGAIN:
if((recve = recvfrom(snoop, buff, 65535, 0, &sn, &sizer)) < 0)
{
perror("recvfrom EAGAIN"); exit(-1);
}
break;
default:
perror("recvfrom"); exit(-1);
break;
}
}
/* for printing packet in hex
for(x =14; x< recve; x++) {
printf(
"%2x"
,ntohs((u_short)buff[x])
);
printf(" ");
}
*/
/* ETH_P_ALL grabs ethernet header which is 14 bytes
so we skip it!
*/
looky.iph = (struct ip *)&buff[14];
/* make sure they are coming from where we sent them */
if(strstr(inet_ntoa(dst), inet_ntoa(looky.iph->ip_src)))
{
/* check if it is TCP */
if(looky.iph->ip_p == 6)
{
looky.tcph = (struct tcphdr *)&buff[14 + sizeof(struct ip)];
if(exi.dport == looky.tcph->th_sport)
{
make_tcp_scroll(looky.tcph, exi.READ_IT);
break;
}
}
/* UDP blah blah, I need better checking to make sure it's
the right packet so don't get pissed at mE!
*/
else if(looky.iph->ip_p == 17)
{
looky.udph = (struct udphdr *)&buff[14 + sizeof(struct ip)];
if(exi.dport == looky.udph->uh_sport)
{
make_udp_scroll(looky.udph, exi.READ_IT);
}
}
} /* if(inet */
}/*while(1) */
}
close(snoop);
} /* if(READ_IT) */
close(s);
return 0;
}
void prterr(char *message)
{ fprintf(stderr, message); }
syntax highlighted by Code2HTML, v. 0.9.1