Hej.
Jeg er i gang med at lave et program som kan tælle antallet af servere som en meddelelse kommer forbi, før den når frem til modtageren, via at bruge rawsockets og TTL.
Men jeg støder ind i et problem når jeg kalder "setsockopt(*s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt))" da dette returnerer en SOCKET_ERROR, med værdien 10022, så hvad gør jeg galt?
koden er som følger:
#include "ip.h"
#define MAX_ADDR_LEN 16
#define MAX_HOSTNAME_LAN 255
FILE *fp;
int Sending(SOCKET *s, int *i, struct sockaddr_in *sin);
void RecvPacket();
int filterpacket(char *buf);
char output[500];
void main()
{
fp = fopen("Sniffer1.txt","a+");
RecvPacket();
fclose(fp);
}
void RecvPacket()
{
SOCKET sock;
WSADATA wsd;
char RecvBuf[65535] = {0};
unsigned int optval = 1;
int i=0;
int k;
if(WSAStartup(MAKEWORD(2,1),&wsd) != 0)
std::cout << "Error: startWinsock" << std::endl;
sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
SOCKADDR_IN sa;
memset(&sa,0,sizeof(SOCKADDR_IN));
sa.sin_family = AF_INET;
sa.sin_port = htons(5000);
sa.sin_addr.s_addr=inet_addr("192.168.0.1");
bind(sock, (SOCKADDR *)&sa, sizeof(sa));
do
{
if(k=Sending(&sock, &(++i), &sa) == SOCKET_ERROR)
std::cout << "Error sending: " << WSAGetLastError() << std::endl;
return;
memset(RecvBuf, 0, sizeof(RecvBuf));
recv(sock, RecvBuf, sizeof(RecvBuf), 0);
filterpacket(RecvBuf);
} while(!(k == SOCKET_ERROR));
}
// Filter the Packet
int filterpacket(char *buf)
{
ipheader *pIpheader;
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];
SOCKADDR_IN saSource, saDest;
int iProtocol, iTTL;
pIpheader = (ipheader *)buf;
//Check Proto
iProtocol = pIpheader->ip_proto;
if(iProtocol==IPPROTO_TCP)
{
fprintf(fp, "Protocol is TCP");
}
if(iProtocol==IPPROTO_UDP)
{
fprintf(fp, "Protocol is UDP");
}
if(iProtocol==IPPROTO_ICMP)
{
fprintf(fp, "Protocol is ICMP");
}
//Check Source IP
saSource.sin_addr.s_addr = pIpheader->ip_source;
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
//Check Dest IP
saDest.sin_addr.s_addr = pIpheader->ip_dest;
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
iTTL = pIpheader->ip_ttl;
fprintf(fp, "%s->%s", (char *)szSourceIP, (char *)szDestIP);
fprintf(fp, "TTL=%d\\n", (char *)iTTL);
return true;
}
int Sending(SOCKET *s, int *i, struct sockaddr_in *sin)
{
char datagram[4096];
bool bOpt = 1;
struct ipheader *iph = (struct ipheader *) datagram;
struct tcpheader *tcph = (struct tcpheader *) datagram + sizeof (struct ipheader);
PS_HDR pseudo_header;
memset (datagram, 0, 4096); /* zero out the buffer */
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof (struct ipheader) + sizeof (struct tcpheader);
iph->ip_id = 1;
iph->ip_off = 0;
iph->ip_ttl = (unsigned char)"5";
iph->ip_proto = 6;
iph->ip_sum = 0;
iph->ip_source = inet_addr ("1.2.3.4");
iph->ip_dest = (*sin).sin_addr.s_addr;
tcph->th_sport = htons (1234);
tcph->th_dport = htons (1234);
tcph->th_seq = rand();
tcph->th_ack = 0;
tcph->th_x2 = 0;
tcph->th_off = 0;
tcph->th_flags = 2; // SYN
tcph->th_win = htons(65535);
tcph->th_sum = 0;
tcph->th_urp = 0;
// Build the Psuedo Header
pseudo_header.source_address = inet_addr ("1.2.3.4");
pseudo_header.dest_address = (*sin).sin_addr.s_addr;
pseudo_header.placeholder = 0;
pseudo_header.protocol = IPPROTO_TCP;
pseudo_header.tcp_length = htons(sizeof(tcpheader));
// Calculate Checksum
tcph->th_sum = checksum((unsigned short *)&pseudo_header, sizeof(pseudo_header));
iph->ip_sum = checksum((unsigned short *)&iph, sizeof(ipheader));
// ENABLE IPHDRINCL
if (setsockopt(*s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt)) == SOCKET_ERROR) {
printf("setsockopt(IP_HDRINCL) failed: %d\\n", WSAGetLastError());
return -1;
}
if (sendto(*s, datagram, sizeof(datagram), 0, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR) {
std::cout << "sendto() failed: " << WSAGetLastError() << std::endl;
return -2;
}
return 0;
}