[linux]raw socket example

来源:互联网 发布:北京洪浪网络诈骗案 编辑:程序博客网 时间:2024/05/21 15:45
#include <arpa/inet.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <net/if.h>#include <netinet/ether.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <netpacket/packet.h>#include <time.h>#include <stdint.h>#include <errno.h>int char2hex(char f){if((f>='0') && (f<='9')) return (f-'0')&0xFF;if((f>='a') && (f<='f')) return (f-'a'+10)&0xFF;if((f>='A') && (f<='F')) return (f-'A'+10)&0xFF;return 0;}uint16_t tcp4_checksum(struct ip *iph, struct tcphdr *tcph){register uint32_t sum = 0;uint16_t answer;uint16_t *addr;int i;addr = (uint16_t*) &(iph->ip_src.s_addr);for(i=0;i<4;++i) sum += *(addr++);sum += htons(iph->ip_p);sum += htons (sizeof (struct tcphdr));i=sizeof(struct tcphdr);addr = (uint16_t*)tcph;while(i>1){sum += *(addr++);i -= 2;}if(i>0) sum += *(uint8_t*)addr;while (sum >> 16) {sum = (sum & 0xffff) + (sum >> 16);}answer = ~sum;return answer;}// Computing the internet checksum (RFC 1071).uint16_t checksum (uint16_t *addr, int len){int count = len;register uint32_t sum = 0;uint16_t answer = 0;// Sum up 2-byte values until none or only one byte left.while (count > 1) {sum += *(addr++);count -= 2;}// Add left-over byte, if any.if (count > 0) {sum += *(uint8_t *) addr;}// Fold 32-bit sum into 16 bits; we lose information by doing this,// increasing the chances of a collision.// sum = (lower 16 bits) + (upper 16 bits shifted right 16 bits)while (sum >> 16) {sum = (sum & 0xffff) + (sum >> 16);}// Checksum is one's compliment of sum.answer = ~sum;return (answer);}int main(const int argc, const char* argv[]){const char* target_ip;const char* target_port;const char* next_hop_address;const char* interface;const int on = 1;int sockfd;struct ifreq if_idx;struct ifreq if_mac;struct sockaddr_in sock_addr;struct ip *iph;struct tcphdr *tcph;uint32_t src_ip;char sync_buf[sizeof(struct ip)+sizeof(struct tcphdr)];if(argc<4){printf("Usage: sync-raw target_ip target_port interface\n");return -1;}srand(time(NULL));target_ip = argv[1];target_port = argv[2];interface = argv[3];sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);if(sockfd<0){printf("socket error %s\n",strerror(errno));return -1;}memset (&if_idx, 0, sizeof (if_idx));strncpy(if_idx.ifr_name, interface, sizeof(if_idx.ifr_name)-1);if(ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0){printf("ioctl SIOCGIFINDEX error %s\n",strerror(errno));return -1;}if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)) < 0) {printf("setsockopt() failed to set IP_HDRINCL %s\n",strerror(errno));return -1;}if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &if_idx, sizeof (if_idx)) < 0) {printf("setsockopt() failed to bind to interface %s \n",strerror(errno));return -1;}memset(&sock_addr,0,sizeof(sock_addr));memset(sync_buf,0,sizeof(sync_buf));iph = (struct ip *)&sync_buf[0];iph->ip_hl = sizeof(struct ip) / sizeof (uint32_t);iph->ip_v = 4;iph->ip_tos = 0;iph->ip_len = htons (sizeof(struct ip)+sizeof(struct tcphdr));iph->ip_id = 0;iph->ip_off = 0;iph->ip_ttl = 64;iph->ip_p = IPPROTO_TCP;if (inet_pton (AF_INET, target_ip, &(iph->ip_dst)) != 1) {printf ("inet_pton failed.\nError message: %s", strerror (errno));return -1;}iph->ip_src = inet_makeaddr((rand()&0x7D)|0x01,0xFFFFFF&(rand()+1));printf("src addr = %s\n",inet_ntoa(iph->ip_src));iph->ip_sum = 0;iph->ip_sum = checksum ((uint16_t *)iph, sizeof(struct ip));tcph = (struct tcphdr *) (&sync_buf[0] + sizeof(struct ip));tcph->source = htons (rand()&0xFFFF);tcph->dest = htons(atoi(target_port)&0xFFFF);tcph->seq = 0;tcph->ack_seq = 0;tcph->res1 = 0;tcph->doff = sizeof(struct tcphdr)/sizeof(int32_t);tcph->fin=0;tcph->syn=1;tcph->rst=0;tcph->psh=0;tcph->ack=0;tcph->urg=0;tcph->res2=0;tcph->window=htons(65535);tcph->urg_ptr=0;tcph->check = tcp4_checksum(iph,tcph);sock_addr.sin_family = AF_INET;sock_addr.sin_addr.s_addr = iph->ip_dst.s_addr;if(sendto(sockfd,sync_buf,sizeof(sync_buf),0,(struct sockaddr *)&sock_addr,sizeof(sock_addr))<0){printf("sendto error %s\n",strerror(errno));return -1;}return 0;}

0 0