ヘッダーでIPアドレス偽装 修正版

・改善した点
ヘッダーとして使えるようにしました。
IpHeaderをgetiph関数内でのみ使用し依存性を下げた。
ところで、これはオプションのことは考えていません。
なので20バイト決めうちです。



#include
#include
#include
#include
#include
#include
#include
#include
#include




unsigned short iphchecksum(unsigned short*);
void getiph(char*, char*, char*, unsigned int, unsigned int, unsigned int);
void iptoint(char*, int*);
int rawsock();
void sends(char*, char*);



/*
int main() {
char h[20];
getiph(h, "1.1.1.1", "2.2.2.2", 0, 0 ,0);
sends(h, "192.168.0.2");
}
*/




void getiph(char *result, char *srcaddress, char *destaddress, unsigned int id, unsigned int df, unsigned int protocol) {
union IpHeader {
unsigned char c[20];
unsigned short s[10];
unsigned int i[5];
} iph;

*iph.c = 69; //バージョンとヘッダ長(1オクテット)
*(iph.c+1) = 0; //TOS(1オクテット)
*(iph.s+1) = 20; //データグラム長(2オクテット)
*(iph.s+2) = id; //ID(2オクテット)
*(iph.s+3) = 0; //フラグメント(2オクテット)
if (df == 1) *(iph.c+6) += 64; //後続パケットの有無
*(iph.c+8) = 64; //TTL(1オクテット)
*(iph.c+9) = (unsigned char)protocol; //プロトコル番号(1オクテット)
*(iph.s+5) = 0; //チェックサム(2オクテット)
int srcip[4] = {}, destip[4] = {};
iptoint(srcaddress, srcip);
iptoint(destaddress, destip);
*(iph.c+12) = *srcip; //srcIP(4オクテット)
*(iph.c+13) = *(srcip+1);
*(iph.c+14) = *(srcip+2);
*(iph.c+15) = *(srcip+3);
*(iph.c+16) = *destip; //destIP(4オクテット)
*(iph.c+17) = *(destip+1);
*(iph.c+18) = *(destip+2);
*(iph.c+19) = *(destip+3);
*(iph.s+5) = iphchecksum(iph.s);
memcpy(result, iph.c, 20);
}


unsigned short iphchecksum(unsigned short *c) {
unsigned int checksum = 0x0;
for (int i=0; i<10; i++) {
checksum += *(c+i);
if (checksum > 0xFFFF) {
checksum -= 0x10000;
checksum += 0x0001;
}
}
return (~(checksum) & 0xFFFF);
}


void iptoint(char *ip, int *result) {
int n[3], pos=0;
char buf[4][4] = {};
for (int i=0; *(ip+i) != '\0'; i++) {
if (*(ip+i) == '.') {
*(n+pos) = i;
pos++;
}
}
memcpy(buf, ip, *(n+1) - *n - 1);
memcpy((buf+1), (ip + *n + 1), *(n+1) - *n - 1);
memcpy((buf+2), (ip + *(n+1) + 1), *(n+2) - *(n+1) - 1);
memcpy((buf+3), (ip + *(n+2) + 1), strlen(ip) - *(n+2) - 1);
*result = atoi(*buf);
*(result+1) = atoi(*(buf+1));
*(result+2) = atoi(*(buf+2));
*(result+3) = atoi(*(buf+3));
}


void sends(char* payload, char *realdestip) {
int sock = rawsock();
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(realdestip);
addr.sin_port = 0;

int err = sendto(sock, payload, 20, 0, (struct sockaddr *) &addr, sizeof(addr));
if (err < 1) {
perror("sendto()");
exit(1);
}
}


int rawsock() {
int sock, on = 1;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock < 0) {
perror("socket()");
exit(1);
}
if ((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on))) <0) {
perror("setsockopt()");
exit(1);
}
return sock;
}