Return to farp_spoofer.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / farp |
1.1 misho 1: /* 2: * Copyright (C) 2010 Martin Willi 3: * Copyright (C) 2010 revosec AG 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "farp_spoofer.h" 17: 18: #include <errno.h> 19: #include <unistd.h> 20: #include <sys/socket.h> 21: #include <linux/if_arp.h> 22: #include <linux/if_ether.h> 23: #include <linux/filter.h> 24: #include <sys/ioctl.h> 25: 26: #include <daemon.h> 27: #include <threading/thread.h> 28: #include <processing/jobs/callback_job.h> 29: 30: typedef struct private_farp_spoofer_t private_farp_spoofer_t; 31: 32: /** 33: * Private data of an farp_spoofer_t object. 34: */ 35: struct private_farp_spoofer_t { 36: 37: /** 38: * Public farp_spoofer_t interface. 39: */ 40: farp_spoofer_t public; 41: 42: /** 43: * Listener that knows active addresses 44: */ 45: farp_listener_t *listener; 46: 47: /** 48: * RAW socket for ARP requests 49: */ 50: int skt; 51: }; 52: 53: /** 54: * IP over Ethernet ARP message 55: */ 56: typedef struct __attribute__((packed)) { 57: uint16_t hardware_type; 58: uint16_t protocol_type; 59: uint8_t hardware_size; 60: uint8_t protocol_size; 61: uint16_t opcode; 62: uint8_t sender_mac[6]; 63: uint8_t sender_ip[4]; 64: uint8_t target_mac[6]; 65: uint8_t target_ip[4]; 66: } arp_t; 67: 68: /** 69: * Send faked ARP response 70: */ 71: static void send_arp(private_farp_spoofer_t *this, 72: arp_t *arp, struct sockaddr_ll *addr) 73: { 74: struct ifreq req; 75: char tmp[4]; 76: 77: req.ifr_ifindex = addr->sll_ifindex; 78: if (ioctl(this->skt, SIOCGIFNAME, &req) == 0 && 79: ioctl(this->skt, SIOCGIFHWADDR, &req) == 0 && 80: req.ifr_hwaddr.sa_family == ARPHRD_ETHER) 81: { 82: memcpy(arp->target_mac, arp->sender_mac, 6); 83: memcpy(arp->sender_mac, req.ifr_hwaddr.sa_data, 6); 84: 85: memcpy(tmp, arp->sender_ip, 4); 86: memcpy(arp->sender_ip, arp->target_ip, 4); 87: memcpy(arp->target_ip, tmp, 4); 88: 89: arp->opcode = htons(ARPOP_REPLY); 90: 91: sendto(this->skt, arp, sizeof(*arp), 0, 92: (struct sockaddr*)addr, sizeof(*addr)); 93: } 94: } 95: 96: /** 97: * ARP request receiving 98: */ 99: static bool receive_arp(private_farp_spoofer_t *this) 100: { 101: struct sockaddr_ll addr; 102: socklen_t addr_len = sizeof(addr); 103: arp_t arp; 104: ssize_t len; 105: host_t *local, *remote; 106: 107: len = recvfrom(this->skt, &arp, sizeof(arp), MSG_DONTWAIT, 108: (struct sockaddr*)&addr, &addr_len); 109: if (len == sizeof(arp)) 110: { 111: local = host_create_from_chunk(AF_INET, 112: chunk_create((char*)&arp.sender_ip, 4), 0); 113: remote = host_create_from_chunk(AF_INET, 114: chunk_create((char*)&arp.target_ip, 4), 0); 115: if (this->listener->has_tunnel(this->listener, local, remote)) 116: { 117: send_arp(this, &arp, &addr); 118: } 119: local->destroy(local); 120: remote->destroy(remote); 121: } 122: 123: return TRUE; 124: } 125: 126: METHOD(farp_spoofer_t, destroy, void, 127: private_farp_spoofer_t *this) 128: { 129: lib->watcher->remove(lib->watcher, this->skt); 130: close(this->skt); 131: free(this); 132: } 133: 134: /** 135: * See header 136: */ 137: farp_spoofer_t *farp_spoofer_create(farp_listener_t *listener) 138: { 139: private_farp_spoofer_t *this; 140: struct sock_filter arp_request_filter_code[] = { 141: BPF_STMT(BPF_LD+BPF_H+BPF_ABS, offsetof(arp_t, protocol_type)), 142: BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_P_IP, 0, 9), 143: BPF_STMT(BPF_LD+BPF_B+BPF_ABS, offsetof(arp_t, hardware_size)), 144: BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 7), 145: BPF_STMT(BPF_LD+BPF_B+BPF_ABS, offsetof(arp_t, protocol_size)), 146: BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 4, 0, 5), 147: BPF_STMT(BPF_LD+BPF_H+BPF_ABS, offsetof(arp_t, opcode)), 148: BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARPOP_REQUEST, 0, 3), 149: BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), 150: BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, sizeof(arp_t), 0, 1), 151: BPF_STMT(BPF_RET+BPF_K, sizeof(arp_t)), 152: BPF_STMT(BPF_RET+BPF_K, 0), 153: }; 154: struct sock_fprog arp_request_filter = { 155: sizeof(arp_request_filter_code) / sizeof(struct sock_filter), 156: arp_request_filter_code, 157: }; 158: 159: INIT(this, 160: .public = { 161: .destroy = _destroy, 162: }, 163: .listener = listener, 164: ); 165: 166: this->skt = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)); 167: if (this->skt == -1) 168: { 169: DBG1(DBG_NET, "opening ARP packet socket failed: %s", strerror(errno)); 170: free(this); 171: return NULL; 172: } 173: 174: if (setsockopt(this->skt, SOL_SOCKET, SO_ATTACH_FILTER, 175: &arp_request_filter, sizeof(arp_request_filter)) < 0) 176: { 177: DBG1(DBG_NET, "installing ARP packet filter failed: %s", strerror(errno)); 178: close(this->skt); 179: free(this); 180: return NULL; 181: } 182: 183: lib->watcher->add(lib->watcher, this->skt, WATCHER_READ, 184: (watcher_cb_t)receive_arp, this); 185: 186: return &this->public; 187: }