I am creating a program that injects tcp packets using SOCK_RAW. I am using Xcode and it confirms all my references are correct, however, when I compile I get a mach-o clang linker(ld) error. I have included all the necessary libs at the top of my code and have never had to import frameworks from osx for c programing before.
I am really lost here. Any help would be appreciated.
checkSum.c:
Code:
#include <stdio.h>
//Check Sum generator (generic)
unsigned short ourCheckSum (unsigned short *buf, int nwords);
unsigned short ourCheckSum (unsigned short *buf, int nwords)
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
RSTSender.c (sorry its longish)
Code:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include "checkSum.c"
int RSTInjector(int connectionSource, int connectionPort, int host);
int RSTInjector(int connectionSource, int connectionPort, int host)
{
//Var
int socketMaster;
char datagram[4096]; //Contains entire packet iphdr + tcphdr
struct ip *iph = (struct ip *) datagram;
struct tcphdr *tcph = (struct tcphdr *) datagram +sizeof(struct ip);
struct sockaddr_in sin;
//Creat Socket
socketMaster = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if (socketMaster == -1){
perror("Could Not Open Socket");
return -1;
}
//
sin.sin_family = AF_INET;
sin.sin_port = htons(connectionPort);
sin.sin_addr.s_addr = inet_addr("127.0.0.1"); // DEST or SRC
//Clean datagram
memset(datagram, 0, 4096);
//Construct Headers
//IP Headers
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
iph->ip_id = htonl(2539);
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0; //csum will be calculated later
iph->ip_src.s_addr = inet_addr("127.0.0.1"); //Connection Source
iph->ip_dst.s_addr = sin.sin_addr.s_addr; //Uses previuse host or connection dest
//TCP Headers
tcph->th_sport = htons(connectionPort); //TCP Port
tcph->th_dport = htons(connectionPort); //TCP Port
tcph->th_seq = rand(); // We really dont care as this is to close a connection
tcph->th_ack = 0; //Is 0 in first packet -- Lets hope it dosent have to be the real value
tcph->th_x2 = 0;
tcph->th_off = 0;
tcph->th_flags = TH_RST; //RST the connection, killing it
tcph->th_win = htonl(65535); //Not sure about this number
tcph->th_sum = 0; // Kernal *should* fill this value in correctly
tcph->th_urp = 0; //What does this do?
//Checksum call
//IP Header
iph->ip_sum = ourCheckSum((unsigned short *) datagram, iph->ip_len >> 1);
//Inform Kernal of header inclusion
{
int one = 1;
const int *val = &one;
if (setsockopt(socketMaster, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0){
perror("Could Not Set HDRINCL");
}
}
//Inject RST Packet
if (sendto(socketMaster, datagram, iph->ip_len, 0, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
perror("Could not inject RST packet");
return -1;
}
else
return 0;
}
and main.c (dont really care about this part yet):
Code:
#include <stdio.h>
#include "RSTSender.c"
int main (int argc, const char * argv[])
{
RSTInjector("127.0.0.1", 20, "127.0.0.1");
}