dics.c revision 302408
1148330Snetchild/*- 2148330Snetchild * Copyright (c) 2006, Andrea Bittau <a.bittau@cs.ucl.ac.uk> 3148330Snetchild * All rights reserved. 4148330Snetchild * 5148330Snetchild * Redistribution and use in source and binary forms, with or without 6148330Snetchild * modification, are permitted provided that the following conditions 7148330Snetchild * are met: 8148330Snetchild * 1. Redistributions of source code must retain the above copyright 9148330Snetchild * notice, this list of conditions and the following disclaimer. 10148330Snetchild * 2. Redistributions in binary form must reproduce the above copyright 11148330Snetchild * notice, this list of conditions and the following disclaimer in the 12148330Snetchild * documentation and/or other materials provided with the distribution. 13148330Snetchild * 14148543Snetchild * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15148543Snetchild * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16215669Snetchild * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17215669Snetchild * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18215669Snetchild * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19215669Snetchild * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20215669Snetchild * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21215669Snetchild * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22215669Snetchild * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23215669Snetchild * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24215669Snetchild * SUCH DAMAGE. 25148330Snetchild * 26215176Spluknet * $FreeBSD: stable/11/tools/tools/net80211/wesside/dics/dics.c 237546 2012-06-25 05:41:16Z kevlo $ 27215176Spluknet */ 28215150Sdim#include <sys/types.h> 29215150Sdim#include <sys/socket.h> 30215051Sattilio#include <sys/select.h> 31215051Sattilio#include <netinet/in.h> 32215051Sattilio#include <arpa/inet.h> 33215051Sattilio#include <netinet/in_systm.h> 34214738Sjhb#include <netinet/ip.h> 35214738Sjhb#include <stdio.h> 36214738Sjhb#include <stdlib.h> 37214738Sjhb#include <unistd.h> 38214738Sjhb#include <string.h> 39214097Savg#define __FAVOR_BSD 40214097Savg#include <netinet/udp.h> 41213700Smm 42213700Smm#if 0 43213644Sgordon#include <pcap.h> 44213644Sgordon#endif 45213644Sgordon 46212435Smdf#define MAGIC_LEN (20+8+5) 47212435Smdf 48211353Sbrueffer#define PRGA_LEN (1500-14-20-8) 49211353Sbrueffer 50210958Sed#define BSD 51210958Sed//#define LINUX 52210958Sed 53210958Sed#ifdef LINUX 54210958Sedstruct ippseudo { 55213387Santoine struct in_addr ippseudo_src; /* source internet address */ 56213387Santoine struct in_addr ippseudo_dst; /* destination internet address */ 57213387Santoine u_char ippseudo_pad; /* pad, must be zero */ 58210538Srpaulo u_char ippseudo_p; /* protocol */ 59210538Srpaulo u_short ippseudo_len; /* protocol length */ 60213387Santoine}; 61213387Santoine#endif 62210299Sed 63210299Sed#define DPORT 6969 64210299Sed#define TTLSENT 128 65210299Sed 66210299Sedint pps = 10; 67210299Sedint poll_rate =5; 68210299Sed 69210299Sed/********** RIPPED 70209973Simp************/ 71209973Simpunsigned short in_cksum (unsigned short *ptr, int nbytes) { 72209640Smarcel register long sum; 73209640Smarcel u_short oddbyte; 74209640Smarcel register u_short answer; 75209640Smarcel 76208099Sdelphij sum = 0; 77208099Sdelphij while (nbytes > 1) 78208099Sdelphij { 79208099Sdelphij sum += *ptr++; 80208099Sdelphij nbytes -= 2; 81207995Sobrien } 82207995Sobrien 83207995Sobrien if (nbytes == 1) 84207995Sobrien { 85207995Sobrien oddbyte = 0; 86207995Sobrien *((u_char *) & oddbyte) = *(u_char *) ptr; 87207995Sobrien sum += oddbyte; 88207995Sobrien } 89207995Sobrien 90207995Sobrien sum = (sum >> 16) + (sum & 0xffff); 91207995Sobrien sum += (sum >> 16); 92207995Sobrien answer = ~sum; 93207995Sobrien return (answer); 94207995Sobrien} 95207995Sobrien/************** 96207995Sobrien************/ 97207995Sobrien 98207995Sobrienvoid hexdump(unsigned char *ptr, int len) { 99206717Sjmallett while(len > 0) { 100206717Sjmallett printf("%.2X ", *ptr); 101206717Sjmallett ptr++; len--; 102206717Sjmallett } 103206695Sjmallett printf("\n"); 104206695Sjmallett} 105206695Sjmallett 106206695Sjmallettint check_signal(int s, char* ip, unsigned char* ttl, unsigned short* port) { 107206695Sjmallett unsigned char buf[1024]; 108206695Sjmallett int rd; 109206695Sjmallett struct msghdr msg; 110206695Sjmallett struct iovec iv; 111205724Smarcel struct sockaddr_in s_in; 112205724Smarcel struct { 113205724Smarcel struct cmsghdr hdr; 114205724Smarcel unsigned char ttl; 115205702Sdelphij } ctl; 116205702Sdelphij 117205702Sdelphij iv.iov_base = buf; 118205702Sdelphij iv.iov_len = sizeof(buf); 119205471Sdelphij 120205471Sdelphij memset(&msg, 0, sizeof(msg)); 121205471Sdelphij memset(&ctl, 0, sizeof(ctl)); 122205471Sdelphij msg.msg_name = &s_in; 123205471Sdelphij msg.msg_namelen = sizeof(s_in); 124205146Sed msg.msg_iov = &iv; 125205146Sed msg.msg_iovlen = 1; 126205146Sed msg.msg_control = &ctl; 127205146Sed msg.msg_controllen = sizeof(ctl); 128204649Sed 129204649Sed rd = recvmsg(s, &msg, 0); 130204426Smarcel if (rd == -1) { 131204426Smarcel perror("recvmsg()"); 132204426Smarcel exit(1); 133204426Smarcel } 134204426Smarcel 135204418Santoine if (rd != 5) 136204418Santoine return 0; 137204418Santoine 138204418Santoine if ( ctl.hdr.cmsg_level != IPPROTO_IP || 139204418Santoine#ifdef LINUX 140204418Santoine ctl.hdr.cmsg_type != IP_TTL 141204418Santoine#else 142204418Santoine ctl.hdr.cmsg_type != IP_RECVTTL 143204418Santoine#endif 144204418Santoine ) { 145202843Sdelphij 146202843Sdelphij printf("Didn't get ttl! len=%d level=%d type=%d\n", 147202843Sdelphij ctl.hdr.cmsg_len, ctl.hdr.cmsg_level, ctl.hdr.cmsg_type); 148202719Sgabor exit(1); 149202719Sgabor } 150202719Sgabor 151202719Sgabor if (memcmp(buf, "sorbo", 5) != 0) 152202719Sgabor return 0; 153202719Sgabor 154202719Sgabor strcpy(ip, inet_ntoa(s_in.sin_addr)); 155202274Sed *ttl = ctl.ttl; 156202274Sed *port = ntohs(s_in.sin_port); 157202215Sed return 1; 158202216Sed} 159202216Sed 160202216Sed#if 0 161202215Sedint check_signal(const unsigned char* buf, int rd, 162202215Sed char* ip, char* ttl, unsigned short *port) { 163202215Sed int got_it; 164202215Sed struct ip* iph; 165202215Sed struct udphdr* uh; 166202215Sed 167202215Sed if (rd != MAGIC_LEN) 168202217Sed return 0; 169202217Sed 170202217Sed iph = (struct ip*) buf; 171202216Sed uh = (struct udphdr*) ((char*)iph + 20); 172201546Sdavidxu 173201546Sdavidxu if ( htons(uh->uh_dport) != DPORT) 174201447Santoine return 0; 175201447Santoine 176201447Santoine got_it = memcmp(&buf[rd-5], "sorbo", 5) == 0; 177201213Strasz 178201213Strasz strcpy(ip, inet_ntoa(iph->ip_src)); 179201213Strasz *ttl = iph->ip_ttl; 180201213Strasz 181201213Strasz *port = ntohs(uh->uh_sport); 182201213Strasz return got_it; 183201213Strasz} 184201213Strasz#endif 185201213Strasz 186201213Straszunsigned int udp_checksum(unsigned char *stuff0, int len, struct in_addr *sip, 187201213Strasz struct in_addr *dip) { 188201213Strasz unsigned char *stuff; 189201213Strasz struct ippseudo *ph; 190201213Strasz 191201213Strasz stuff = (unsigned char*) malloc(len + sizeof(struct ippseudo)); 192201213Strasz if(!stuff) { 193201213Strasz perror("malloc()"); 194201213Strasz exit(1); 195201213Strasz } 196201213Strasz 197201213Strasz ph = (struct ippseudo*) stuff; 198201213Strasz 199201213Strasz memcpy(&ph->ippseudo_src, sip, 4); 200200028Sume memcpy(&ph->ippseudo_dst, dip, 4); 201200028Sume ph->ippseudo_pad = 0; 202200028Sume ph->ippseudo_p = IPPROTO_UDP; 203200130Santoine ph->ippseudo_len = htons(len); 204199463Sdelphij 205199463Sdelphij memcpy(stuff + sizeof(struct ippseudo), stuff0, len); 206200130Santoine 207200130Santoine return in_cksum((unsigned short*)stuff, len+sizeof(struct ippseudo)); 208198538Skib} 209198538Skib 210198443Santoinevoid send_stuff(int s, char* sip, char* ip, unsigned short port, int dlen) { 211198443Santoine static unsigned char buf[PRGA_LEN+128] = "\x69"; 212198443Santoine static int plen = 0; 213197081Sdelphij static struct sockaddr_in dst; 214197081Sdelphij int rd; 215197081Sdelphij struct in_addr tmp_dst; 216196787Sremko int stuff, delay; 217196787Sremko int i; 218196787Sremko 219196787Sremko stuff = poll_rate*pps; 220196787Sremko delay = (int) ((double)1.0/pps*1000.0*1000.0); 221196768Sflz 222196768Sflz inet_aton(ip, &tmp_dst); 223196768Sflz if (tmp_dst.s_addr != dst.sin_addr.s_addr || 224196768Sflz dlen != (plen - 20 - 8)) { 225198443Santoine 226198443Santoine buf[0] = '\x69'; 227198443Santoine } 228198443Santoine 229198443Santoine // create packet 230198443Santoine if (buf[0] == '\x69') { 231198443Santoine struct ip* iph; 232198443Santoine struct udphdr* uh; 233198443Santoine char* ptr; 234198443Santoine 235198443Santoine// printf("Initializing packet...\n"); 236198443Santoine memset(buf, 0, sizeof(buf)); 237198443Santoine iph = (struct ip*) buf; 238198443Santoine iph->ip_hl = 5; 239198443Santoine iph->ip_v = 4; 240198443Santoine iph->ip_tos = 0; 241198443Santoine iph->ip_len = htons(20+8+dlen); 242198443Santoine iph->ip_id = htons(666); 243198443Santoine iph->ip_off = 0; 244198443Santoine iph->ip_ttl = TTLSENT; 245198443Santoine iph->ip_p = IPPROTO_UDP; 246198443Santoine iph->ip_sum = 0; 247198443Santoine 248198443Santoine inet_aton(sip, &iph->ip_src); 249198443Santoine inet_aton(ip, &iph->ip_dst); 250198443Santoine 251198443Santoine memset(&dst, 0, sizeof(dst)); 252198443Santoine dst.sin_family = PF_INET; 253198443Santoine dst.sin_port = htons(port); 254198443Santoine memcpy(&dst.sin_addr, &iph->ip_dst, sizeof(dst.sin_addr)); 255198443Santoine 256198443Santoine iph->ip_sum = in_cksum((unsigned short*)iph, 20); 257198443Santoine 258198443Santoine uh = (struct udphdr*) ((char*)iph + 20); 259198443Santoine uh->uh_sport = htons(DPORT); 260198443Santoine uh->uh_dport = htons(port); 261198443Santoine uh->uh_ulen = htons(8+dlen); 262198443Santoine uh->uh_sum = 0; 263198443Santoine 264198443Santoine ptr = (char*) uh + 8; 265198443Santoine 266198443Santoine memset(ptr, 0, dlen); 267198443Santoine 268196019Srwatson uh->uh_sum = udp_checksum((unsigned char*)uh, 8+dlen, 269196019Srwatson &iph->ip_src, &iph->ip_dst); 270195767Skensmith 271195767Skensmith#ifdef BSD 272195767Skensmith iph->ip_len = ntohs(iph->ip_len); 273195767Skensmith#endif 274195767Skensmith plen = 20+8+dlen; 275195767Skensmith } 276195767Skensmith#if 0 277195767Skensmith printf("Packet %d %s %d\n", plen, inet_ntoa(dst.sin_addr), 278195767Skensmith ntohs(dst.sin_port)); 279195767Skensmith hexdump (buf, plen); 280195767Skensmith#endif 281195767Skensmith 282195767Skensmith// printf("sending stuff to %s\n", ip); 283195767Skensmith for (i = 0; i < stuff; i++) { 284195767Skensmith rd = sendto(s, buf, plen, 0, (struct sockaddr*)&dst, sizeof(dst)); 285195767Skensmith if (rd == -1) { 286195767Skensmith perror("sendto()"); 287195767Skensmith exit(1); 288195767Skensmith } 289195767Skensmith if (rd != plen) { 290195767Skensmith printf("wrote %d out of %d\n", rd, plen); 291195767Skensmith exit(1); 292195767Skensmith } 293195767Skensmith 294195767Skensmith // sending ttl.. 295195767Skensmith if (dlen != PRGA_LEN) 296195767Skensmith break; 297195767Skensmith usleep(delay); 298195767Skensmith } 299195767Skensmith} 300195767Skensmith 301195767Skensmithint main(int argc, char *argv[]) { 302195767Skensmith int s, us; 303195767Skensmith int rd = 1; 304195767Skensmith 305195767Skensmith#if 0 306195767Skensmith const u_char* buf; 307195767Skensmith char errbuf[PCAP_ERRBUF_SIZE]; 308195767Skensmith struct pcap_pkthdr phdr; 309195767Skensmith pcap_t* p; 310195767Skensmith int dtl; 311195767Skensmith#endif 312195767Skensmith 313195767Skensmith int got_it = 0; 314195767Skensmith char ip[16] = "\x00"; 315195767Skensmith unsigned char ttl = 0; 316195767Skensmith unsigned short port; 317195767Skensmith struct sockaddr_in s_in; 318195767Skensmith struct timeval tv; 319195767Skensmith fd_set rfds; 320195767Skensmith unsigned char* sip = 0; 321195767Skensmith 322195767Skensmith if (argc < 2) { 323195767Skensmith printf("Usage: %s <sip> [pps]\n", argv[0]); 324195767Skensmith exit(1); 325195767Skensmith } 326195767Skensmith 327195767Skensmith if (argc > 2) { 328195767Skensmith pps = atoi(argv[2]); 329195767Skensmith } 330195767Skensmith 331195767Skensmith printf("PPS=%d\n", pps); 332195767Skensmith 333195767Skensmith sip = argv[1]; 334195767Skensmith 335195767Skensmith memset(&s_in, 0, sizeof(s_in)); 336195767Skensmith us = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 337195767Skensmith if (s == -1) { 338195767Skensmith perror("socket()"); 339195767Skensmith exit(1); 340195767Skensmith } 341195767Skensmith s_in.sin_family = PF_INET; 342195767Skensmith s_in.sin_addr.s_addr = INADDR_ANY; 343195767Skensmith s_in.sin_port = htons(DPORT); 344195789Santoine if (bind (us, (struct sockaddr*)&s_in, sizeof(s_in)) == -1) { 345195767Skensmith perror("bind()"); 346195767Skensmith exit(1); 347195767Skensmith } 348195767Skensmith 349195767Skensmith rd = 1; 350195767Skensmith if (setsockopt(us, IPPROTO_IP, IP_RECVTTL, &rd, sizeof(rd)) == -1) { 351195767Skensmith perror("setsockopt()"); 352195767Skensmith exit(1); 353195767Skensmith } 354195767Skensmith 355195767Skensmith s = socket (PF_INET, SOCK_RAW, IPPROTO_UDP); 356195767Skensmith if (s == -1) { 357195767Skensmith perror("socket()"); 358195767Skensmith exit(1); 359195767Skensmith } 360195767Skensmith 361195767Skensmith rd = 1; 362195767Skensmith if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &rd, sizeof(rd)) == -1) { 363195767Skensmith perror("setsockopt()"); 364195767Skensmith exit(1); 365195767Skensmith } 366195767Skensmith 367195767Skensmith 368195767Skensmith#if 0 369195767Skensmith p = pcap_open_live(argv[1], 512, 0, 25, errbuf); 370195767Skensmith if (!p) { 371195767Skensmith printf("pcap_open_live(): %s\n", errbuf); 372195767Skensmith exit(1); 373195767Skensmith } 374195767Skensmith 375195767Skensmith dtl = pcap_datalink(p); 376195767Skensmith 377195767Skensmith switch (dtl) { 378195767Skensmith case DLT_NULL: 379195767Skensmith dtl = 4; 380195767Skensmith break; 381195767Skensmith 382195767Skensmith case DLT_EN10MB: 383195767Skensmith dtl = 14; 384195767Skensmith break; 385195767Skensmith 386195767Skensmith default: 387195767Skensmith printf("Unknown datalink %d\n", dtl); 388195767Skensmith exit(1); 389195767Skensmith } 390195767Skensmith 391195767Skensmith printf("Datalink size=%d\n", dtl); 392195767Skensmith#endif 393195767Skensmith while (1) { 394195767Skensmith#if 0 395195767Skensmith buf = pcap_next(p, &phdr); 396195767Skensmith if (buf) { 397195767Skensmith if (check_signal(buf+dtl, phdr.caplen-dtl, 398195767Skensmith ip, &ttl, &port)) { 399195767Skensmith got_it = 2; 400195767Skensmith printf("Got signal from %s:%d TTL=%d\n", 401195767Skensmith ip, port, ttl); 402195767Skensmith } 403195767Skensmith } 404195767Skensmith#endif 405195767Skensmith FD_ZERO(&rfds); 406195767Skensmith FD_SET(us, &rfds); 407195767Skensmith tv.tv_sec = 0; 408195767Skensmith tv.tv_usec = 10*1000; 409195767Skensmith rd = select(us+1, &rfds, NULL, NULL, &tv); 410195767Skensmith if (rd == -1) { 411195767Skensmith perror("select()"); 412195767Skensmith exit(1); 413195767Skensmith } 414195767Skensmith if (rd == 1 && FD_ISSET(us, &rfds)) { 415195767Skensmith char ipnew[16]; 416195767Skensmith unsigned char ttlnew; 417195767Skensmith if (check_signal(us, ipnew, &ttlnew, &port)) { 418195767Skensmith int send_ttl = 0; 419195767Skensmith if (ttlnew != ttl || strcmp(ipnew, ip) != 0 || 420195767Skensmith got_it == 0) { 421195767Skensmith send_ttl = 1; 422195767Skensmith } 423195767Skensmith ttl = ttlnew; 424195767Skensmith strcpy(ip, ipnew); 425195767Skensmith 426195767Skensmith printf("Got signal from %s:%d TTL=%d\n", 427195767Skensmith ip, port, ttl); 428195767Skensmith got_it = 2; 429195767Skensmith 430195767Skensmith if (send_ttl) { 431195767Skensmith printf("Sending ttl (%d)...\n", ttl); 432195767Skensmith send_stuff(s, sip, ip, port, 69 + (TTLSENT-ttl)); 433195767Skensmith } 434195767Skensmith } 435195767Skensmith } 436195767Skensmith 437195767Skensmith if (got_it) { 438195767Skensmith printf("Sending stuff to %s...\n", ip); 439195767Skensmith send_stuff(s, sip, ip, port, PRGA_LEN); 440195767Skensmith got_it--; 441195767Skensmith 442195767Skensmith if (got_it == 0) { 443195767Skensmith printf("Stopping send\n"); 444195767Skensmith } 445195767Skensmith } 446195767Skensmith } 447195767Skensmith 448195767Skensmith#if 0 449195767Skensmith pcap_close(p); 450195767Skensmith#endif 451195767Skensmith 452195767Skensmith close(s); 453195767Skensmith close(us); 454195767Skensmith exit(0); 455195767Skensmith} 456195767Skensmith