?? send_arp.c
字號:
/* send_arp.c This program sends out one ARP packet with source/target IP and Ethernet hardware addresses suuplied by the user. It compiles and works on Linux and will probably work on any Unix that has SOCK_PACKET. volobuev@t1.chem.umn.edu */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <arpa/inet.h> #include <linux/if_ether.h> #define ETH_HW_ADDR_LEN 6 #define IP_ADDR_LEN 4 #define ARP_FRAME_TYPE 0x0806 #define ETHER_HW_TYPE 1 #define IP_PROTO_TYPE 0x0800 #define OP_ARP_REQUEST 2 #define DEFAULT_DEVICE "eth0" char usage[] = {"send_arp: sends out custom ARP packet. yuri volobuev\n\ \tusage: send_arp src_ip_addr src_hw_addr targ_ip_addr tar_hw_addr\n\n"}; struct arp_packet { u_char targ_hw_addr[ETH_HW_ADDR_LEN]; u_char src_hw_addr[ETH_HW_ADDR_LEN]; u_short frame_type; u_short hw_type; u_short prot_type; u_char hw_addr_size; u_char prot_addr_size; u_short op; u_char sndr_hw_addr[ETH_HW_ADDR_LEN]; u_char sndr_ip_addr[IP_ADDR_LEN]; u_char rcpt_hw_addr[ETH_HW_ADDR_LEN]; u_char rcpt_ip_addr[IP_ADDR_LEN]; u_char padding[18]; }; void die (char *); void get_ip_addr (struct in_addr *, char *); void get_hw_addr (char *, char *); int main (int argc, char * argv[]) { struct in_addr src_in_addr, targ_in_addr; struct arp_packet pkt; struct sockaddr sa; int sock; if (argc != 5) die(usage); sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_RARP)); if (sock < 0) { perror("socket"); exit(1); } pkt.frame_type = htons(ARP_FRAME_TYPE); pkt.hw_type = htons(ETHER_HW_TYPE); pkt.prot_type = htons(IP_PROTO_TYPE); pkt.hw_addr_size = ETH_HW_ADDR_LEN; pkt.prot_addr_size = IP_ADDR_LEN; pkt.op = htons(OP_ARP_REQUEST); get_hw_addr(pkt.targ_hw_addr, argv[4]); get_hw_addr(pkt.rcpt_hw_addr, argv[4]); get_hw_addr(pkt.src_hw_addr, argv[2]); get_hw_addr(pkt.sndr_hw_addr, argv[2]); get_ip_addr(&src_in_addr, argv[1]); get_ip_addr(&targ_in_addr, argv[3]); memcpy(pkt.sndr_ip_addr, &src_in_addr, IP_ADDR_LEN); memcpy(pkt.rcpt_ip_addr,
&targ_in_addr, IP_ADDR_LEN); bzero(pkt.padding,18); strcpy(sa.sa_data,DEFAULT_DEVICE); if (sendto(sock,&pkt,sizeof(pkt),0,&sa,sizeof(sa)) < 0) { perror("sendto"); exit(1); } exit(0); } void die (char *str) { fprintf(stderr,"%s\n",str); exit(1); } void get_ip_addr (struct in_addr *in_addr, char *str) { struct hostent *hostp; in_addr->s_addr = inet_addr(str); if(in_addr->s_addr == -1){ if ((hostp = gethostbyname(str))) bcopy(hostp->h_addr, in_addr, hostp->h_length); else { fprintf(stderr, "send_arp: unknown host %s\n", str); exit(1); } } } void get_hw_addr (char *buf, char *str) { int i; char c, val; for(i = 0; i < ETH_HW_ADDR_LEN; i++) { if (!(c = tolower(*str++))) die("Invalid hardware address"); if (isdigit(c)) val = c - '0'; else if (c >= 'a' && c <= 'f') val = c-'a'+10; else die("Invalid hardware address"); *buf = val << 4; if (!(c = tolower(*str++))) die("Invalid hardware address"); if (isdigit(c)) val = c - '0'; else if (c >= 'a' && c <= 'f') val = c-'a'+10; else die("Invalid hardware address"); *buf++ |= val; if (*str == ':') str++; } } /* icmp_redir.c This program sends out an ICMP host redirect packet with gateway IP supplied by user. It was written and tested under Linux 2.0.30 and could be rather easily modified to work on most Unices. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <netdb.h> #include <syslog.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/ip_icmp.h> #include <netinet/ip.h> #define IPVERSION 4 struct raw_pkt { struct iphdr ip; /* This is Linux-style iphdr. Use BSD-style struct ip if you want */ struct icmphdr icmp; struct iphdr encl_iphdr; char encl_ip_data[8]; }; struct raw_pkt *pkt; void die (char *); unsigned long int get_ip_addr (char *); unsigned short checksum (unsigned short *, char); int main (int argc, char * argv[]) { struct sockaddr_in sa; int sock, packet_len; char usage[] = {"icmp_redir: send out custom ICMP host redirect packet. \ yuri volobuev'97\n\ usage: icmp_redir
gw_host targ_host dst_host dummy_host\n"}; char on = 1; if (argc != 5) die(usage); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror("socket"); exit(1); } sa.sin_addr.s_addr = get_ip_addr(argv[2]); sa.sin_family = AF_INET; packet_len = sizeof(struct raw_pkt); pkt = calloc((size_t)1, (size_t)packet_len); pkt->ip.version = IPVERSION; pkt->ip.ihl = sizeof(struct iphdr) >> 2; pkt->ip.tos = 0; pkt->ip.tot_len = htons(packet_len); pkt->ip.id = htons(getpid() & 0xFFFF); pkt->ip.frag_off = 0; pkt->ip.ttl = 0x40; pkt->ip.protocol = IPPROTO_ICMP; pkt->ip.check = 0; pkt->ip.saddr = get_ip_addr(argv[1]); pkt->ip.daddr = sa.sin_addr.s_addr; pkt->ip.check = checksum((unsigned short*)pkt, sizeof(struct iphdr)); pkt->icmp.type = ICMP_REDIRECT; pkt->icmp.code = ICMP_REDIR_HOST; pkt->icmp.checksum = 0; pkt->icmp.un.gateway = get_ip_addr(argv[4]); memcpy(&(pkt->encl_iphdr), pkt, sizeof(struct iphdr)); pkt->encl_iphdr.protocol = IPPROTO_IP; pkt->encl_iphdr.saddr = get_ip_addr(argv[2]); pkt->encl_iphdr.daddr = get_ip_addr(argv[3]); pkt->encl_iphdr.check = 0; pkt->encl_iphdr.check = checksum((unsigned short*) & (pkt->encl_iphdr), sizeof(struct iphdr)); pkt->icmp.checksum = checksum((unsigned short*) & (pkt->icmp), sizeof(struct raw_pkt)-sizeof(struct iphdr)); if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) { perror("setsockopt: IP_HDRINCL"); exit(1); } if(sendto(sock, pkt, packet_len, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0){ perror("sendto"); exit(1); } exit(0); } void die (char *str) { fprintf(stderr, "%s\n", str); exit(1); } unsigned long int get_ip_addr (char *str) { struct hostent *hostp; unsigned long int addr; if( (addr = inet_addr(str)) == -1){ if ((hostp = gethostbyname(str))) return *(unsigned long int *)(hostp->h_addr); else { fprintf(stderr, "unknown host %s\n", str); exit(1); } } return addr; } unsigned short checksum(unsigned short* addr,char len){ register long sum = 0; while (len > 1) { sum += *addr++; len -= 2; } if (len > 0) sum += *addr; while (sum >> 16) sum = (sum & 0
xffff) + (sum >> 16); return ~sum; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -