int main(int argc, char** argv) { char devname[IFNAMSIZ]; int ifd, pingd; fd_set fds; int maxfd; struct timeval tv; struct in_addr me; int mask, server; char packet[PACKLEN]; int len,tmp; struct sockaddr_in sa; struct in_addr buf; socklen_t buflen; struct icmphdr* icmph; int iphl; int faddr, taddr; int id, seq=0; if(argc<3) { dbg("ICMP-Proxy, by koala_man\n"); dbg("Usage: %s magic ip\n",argv[0]); dbg("Magic is any 2-char string, same for server and client\n"); dbg("For clients: ip is the public address for the server\n"); dbg("For servers: ip is the private /24-mask for clients\n"); exit(1); } if(inet_aton(argv[2],&me)<0) { perror("inet_aton"); exit(1); } if(argv[1][0]!=0) id=argv[1][1]<<8; id=id | argv[1][0]; dbg("Using id %x\n",id); server=(((me.s_addr)>>24)&0xFF)==0; mask=htonl(me.s_addr); dbg("You're a %s\n",server?"server":"client"); dbg("Mask is %d: %s\n",mask,ntoa(mask)); strncpy(devname,"it%d",IFNAMSIZ); ifd=opentun(devname); dbg("Opened tun as %s\n",devname); if((pingd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket"); close(ifd); exit(3); } targets=(int*)calloc(256,sizeof(struct in_addr)); maxfd=MAX(ifd,pingd)+1; FD_ZERO(&fds); while(1) { FD_SET(pingd,&fds); FD_SET(ifd,&fds); tv.tv_sec=8; //XXX tv.tv_usec=0; dbg("\n"); tmp=select(maxfd,&fds,NULL,NULL,&tv); if(tmp==0) { if(server) continue; icmph=(struct icmphdr*) packet; icmph->type=ICMP_ECHO; icmph->code=0; icmph->checksum=0; icmph->un.echo.sequence=seq++; icmph->un.echo.id=id; tmp=(sizeof(struct icmphdr)); icmph->checksum=in_sum(packet,tmp,0); buflen=sizeof(struct sockaddr); sa.sin_addr=me; sendto(pingd,packet,tmp,0,(struct sockaddr*)&sa,buflen); dbg("Ping!\n"); } else { if(FD_ISSET(pingd,&fds)) { dbg("Got a ping\n"); buflen=sizeof(struct sockaddr); len=recvfrom(pingd,packet,PACKLEN,0,(struct sockaddr*)&sa,&buflen); dbg("Recvfrom=%d\n",len); iphl=packet[0]&0x0F; dbg("Packet header: %d\n",iphl); if(iphl<5) { dbg("Bad packet, too short header.\n"); continue; } taddr=ntohl(((int*)packet)[3]); //tunnel from faddr=ntohl(((int*)packet)[iphl+8/4+3]); //packet from if(!(taddr==mask || (server && (faddr & ~0xff)==mask))) { dbg("IP from wrong place\n"); dbg(" Is %s\n",ntoa(faddr)); dbg(" or %s\n",ntoa(taddr)); dbg(" Should be %s\n",ntoa(mask)); continue; } icmph=(struct icmphdr*)(packet+iphl*4); if(icmph->type != ICMP_ECHOREPLY) { dbg("Not ICMP_ECHOREPLY\n"); continue; } if(icmph->un.echo.id!=id) { dbg("Wrong ID\n"); continue; } if((len-iphl*4)<20 || len>PACKLEN) { dbg("Not sane size\n"); continue; } if(server) { dbg("Setting %x to %x\n",faddr,taddr); settarget(faddr & 0xff,htonl(taddr)); } write(ifd,packet+iphl*4+8,len-iphl*4-8); } if(FD_ISSET(ifd,&fds)) { dbg("Got from if\n"); icmph=(struct icmphdr*) packet; icmph->type=ICMP_ECHOREPLY; icmph->code=0; icmph->checksum=0; icmph->un.echo.sequence=htons(seq++); icmph->un.echo.id=id; len=read(ifd,packet+8,TUNLEN); dbg("read=%d\n",len); if(len<0) { perror("Read from if"); exit(4); } if(len==0) { dbg("no data, lol?\n"); continue; } icmph->checksum=in_sum(packet,8+len,0); buflen=sizeof(struct sockaddr); if(server) { tmp=ntohl(((int*)packet)[8/4+4]); buf.s_addr=findtarget(tmp&0xff); if(buf.s_addr==0) { dbg("Don't know where to send, dropping\n"); continue; } sa.sin_addr=buf; } else { sa.sin_addr=me; } sendto(pingd,packet,len+8,0,(struct sockaddr*)&sa,buflen); } } } buflen=sizeof(struct sockaddr); len=recvfrom(pingd,packet,PACKLEN,0,(struct sockaddr*)&sa,&buflen); dbg("Recvfrom=%d\n",len); write(2,packet,len); close(ifd); close(pingd); return 0; }
const Real GreensFunction2DAbs::p_int_theta_second(const Real r, const Real theta, const Real t) const { const Real r_0(this->getr0()); const Real a(this->geta()); const Real minusDt(-1e0 * this->getD() * t); const Integer num_in_term_use(100); const Integer num_out_term_use(100); const Real threshold(CUTOFF); Real sum(0e0); Real term(0e0); Integer n(1); for(; n < num_out_term_use; ++n) { Real in_sum(0e0); Real in_term(0e0); Real in_term1(0e0); Real in_term2(0e0); Real in_term3(0e0); Real a_alpha_mn(0e0); Real alpha_mn(0e0); Real Jn_r_alpha_mn(0e0); Real Jn_r0_alpha_mn(0e0); Real Jn_d_1_a_alpha_mn(0e0);// J_n-1(a alpha_mn) Real Jn_p_1_a_alpha_mn(0e0);// J_n+1(a alpha_mn) Real n_real(static_cast<double>(n)); int n_int(static_cast<int>(n)); Integer m(1); for(; m < num_in_term_use; ++m) { a_alpha_mn = gsl_sf_bessel_zero_Jnu(n_real, m); alpha_mn = a_alpha_mn / a; Jn_r_alpha_mn = gsl_sf_bessel_Jn(n_int, r * alpha_mn); Jn_r0_alpha_mn = gsl_sf_bessel_Jn(n_int, r_0 * alpha_mn); Jn_d_1_a_alpha_mn = gsl_sf_bessel_Jn(n_int - 1, a_alpha_mn); Jn_p_1_a_alpha_mn = gsl_sf_bessel_Jn(n_int + 1, a_alpha_mn); in_term1 = std::exp(alpha_mn * alpha_mn * minusDt); in_term2 = Jn_r_alpha_mn * Jn_r0_alpha_mn; in_term3 = Jn_d_1_a_alpha_mn - Jn_p_1_a_alpha_mn; in_term = in_term1 * in_term2 / (in_term3 * in_term3); in_sum += in_term; // std::cout << "inner sum " << in_sum << ", term" << in_term << std::endl; if(fabs(in_term/in_sum) < threshold) { // std::cout << "normal exit. m = " << m << " second term" << std::endl; break; } } if(m == num_in_term_use) std::cout << "warning: use term over num_in_term_use" << std::endl; // term = in_sum * std::cos(n_real * theta); term = in_sum * std::sin(n_real * theta) / n_real; sum += term; // std::cout << "outer sum " << sum << ", term" << term << std::endl; if(fabs(in_sum / (n_real * sum)) < threshold) { /* if n * theta is a multiple of \pi, the term may be zero and * * term/sum become also zero. this is a problem. sin is in a * * regeon [-1, 1], so the order of term does not depend on * * value of sin, so this considers only (in_sum / n_real). */ // std::cout << "normal exit. n = " << n << " second term" << std::endl; break; } } if(n == num_out_term_use) std::cout << "warning: use term over num_out_term_use" << std::endl; return (8e0 * sum / (M_PI * a * a)); }