int main(void) { //init: DAC_DeInit(); init_GPIOA(); init_GPIOC(); init_GPIOD(); init_DMA1(); init_DMA2(); init_TIM2(); init_TIM3(); init_TIM4(); init_TIM6(); init_ADC3(); init_DAC(); init_filter(&ap_1); init_filter(&ap_2); init_filter(&ap_3); init_filter(&ap_4); ap_filter_coefs(&ap_1); ap_filter_coefs(&ap_2); ap_filter_coefs(&ap_3); ap_filter_coefs(&ap_4); ADC_SoftwareStartConv(ADC3); while (1) { counter++; } }
static void init_user(char * name) { Filter * filter = init_filter(); filter->ft = USER_FILTER; filter->cmd = user_filter; filter->info = name; push_op_stack(filter); }
static void init_group(char * name) { Filter * filter = init_filter(); filter->ft = GROUP_FILTER; filter->cmd = group_filter; filter->info = name; push_op_stack(filter); }
static void init_perm(char * name) { Filter * filter = init_filter(); filter->ft = PERM_FILTER; filter->cmd = perm_filter; filter->info = name; push_op_stack(filter); }
static void init_filesize(char * size) { Filter * filter = init_filter(); filter->ft = FILESIZE_FILTER; filter->cmd = filesize_filter; filter->info = size; push_op_stack(filter); }
static void filter_not() { Filter * first = pop_op_stack(); Filter * nfa = init_filter(); init_not_filter_adapter(nfa); set_not_adapter_info(nfa, first); push_op_stack(nfa); }
// TODO: filters should be stored in matrix Mat[M][N], where M = index of output_context and N = index of input_stream // map to translate stream index in input contexts to stream index in output context static int init_filters(AVFormatContext* input_context, AVFormatContext* output_context) { const char* filterSpec; unsigned int i; int ret; _filterCtx = (FilteringContext*)av_malloc_array(input_context->nb_streams, sizeof(*_filterCtx)); if (!_filterCtx) return AVERROR(ENOMEM); for (i = 0; i < input_context->nb_streams; i++) { _filterCtx[i].BuffersrcCtx = NULL; _filterCtx[i].BuffersinkCtx = NULL; _filterCtx[i].FilterGraph = NULL; if (!(input_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO || input_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)) continue; if (input_context->streams[i]->codec->codec_id == output_context->streams[i+1]->codec->codec_id) continue; if (input_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) filterSpec = "null"; /* passthrough (dummy) filter for video */ else filterSpec = "anull"; /* passthrough (dummy) filter for audio */ ret = init_filter(&_filterCtx[i], input_context->streams[i]->codec, output_context->streams[i+1]->codec, filterSpec); if (ret) return ret; } return 0; }
static int init_filters(void) { const char *filter_spec; unsigned int i; int ret; filter_ctx = av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx)); if (!filter_ctx) return AVERROR(ENOMEM); for (i = 0; i < ifmt_ctx->nb_streams; i++) { filter_ctx[i].buffersrc_ctx = NULL; filter_ctx[i].buffersink_ctx = NULL; filter_ctx[i].filter_graph = NULL; if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO || ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)) continue; if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) filter_spec = "null"; /* passthrough (dummy) filter for video */ else filter_spec = "anull"; /* passthrough (dummy) filter for audio */ ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec, ofmt_ctx->streams[i]->codec, filter_spec); if (ret) return ret; } return 0; }
static void init_filetype(char * ft) { Filter * filter = init_filter(); filter->ft = FILETYPE_FILTER; filter->cmd = filetype_filter; filter->info = ft; push_op_stack(filter); }
static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, struct mp_audio **out) { struct spdifContext *spdif_ctx = da->priv; spdif_ctx->out_buffer_len = 0; if (!mpkt) return 0; double pts = mpkt->pts; AVPacket pkt; mp_set_av_packet(&pkt, mpkt, NULL); mpkt->len = 0; // will be fully consumed pkt.pts = pkt.dts = 0; if (!spdif_ctx->lavf_ctx) { if (init_filter(da, &pkt) < 0) return -1; } int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt); avio_flush(spdif_ctx->lavf_ctx->pb); if (ret < 0) return -1; int samples = spdif_ctx->out_buffer_len / spdif_ctx->fmt.sstride; *out = mp_audio_pool_get(spdif_ctx->pool, &spdif_ctx->fmt, samples); if (!*out) return -1; memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len); (*out)->pts = pts; return 0; }
static void init_filters(LoggerConfig *loggerConfig) { ImuConfig *config = loggerConfig->ImuConfigs; for (size_t i = 0; i < CONFIG_IMU_CHANNELS; i++) { float alpha = (config + i)->filterAlpha; init_filter(&g_imu_filter[i], alpha); } }
/** * regex filter */ static void init_reg(char * pattern) { int cflags = 0; Filter * filter = init_filter(); filter->ft = REG_FILTER; filter->cmd = reg_filter; filter->info = malloc(sizeof(regex_t)); regcomp(filter->info, pattern, cflags); push_op_stack(filter); }
static void init_fnmatch(char * pattern, bool case_s) { Filter * filter = init_filter(); struct fn_option * fo = (struct fn_option *)malloc(sizeof(struct fn_option)); fo->case_s = case_s; fo->pattern = pattern; filter->info = fo; filter->ft = FNMATCH_FILTER; filter->cmd = fnmatch_filter; push_op_stack(filter); }
int lrnproc(){ /* 構造体のメモリ確保 */ // 学習データ構造体 Lrndata *plrndata; plrndata = (Lrndata *)malloc(sizeof(Lrndata)); //initldata(plrndata); // 畳み込みとプーリング処理関連構造体 Filter *pflt; pflt = (Filter *)malloc(sizeof(Filter)); Convout *pconv; pconv = (Convout *)malloc(sizeof(Convout)); Poolout *ppool; ppool = (Poolout *)malloc(sizeof(Poolout)); /* 構造体のメモリ確保完了 */ // 学習データをセット setldata(plrndata); // debug_info getldata(plrndata); // フィルター初期化 init_filter(pflt); get_filter(pflt); // sleep(5); // 畳み込みの計算 conv(pflt, plrndata, pconv); get_convout(pconv); // プーリングの計算 pool(pconv, ppool); get_poolout(ppool); // メモリ解放 free(plrndata); free(pflt); free(pconv); free(ppool); return 0; }
/************************************************************************** Opens the filter window **************************************************************************/ void filter_open(void) { #if 0 if (!filter_wnd) { init_filter(); if (!filter_wnd) return; } set(filter_wnd, MUIA_Window_Open, TRUE); #endif }
int timer_init(LoggerConfig *loggerConfig) { for (size_t i = 0; i < CONFIG_TIMER_CHANNELS; i++) { TimerConfig *tc = &loggerConfig->TimerConfigs[i]; const uint32_t qp_us = get_quiet_period(tc); timer_device_init(i, tc->timerSpeed, qp_us, tc->edge); init_filter(&g_timer_filter[i], tc->filterAlpha); } return 1; }
int main(void) { int ret; int len; int inside = 0; init_filter(); while(1) { ret = scanf("%1023s", in_buff); if (ret == EOF) break; if (ret == 0) continue; len = strlen(in_buff); switch (in_buff[len-1]) { case ':': { if (check_filter(in_buff)) { printf("\n%s", in_buff); inside = 1; } else { inside = 0; } break; } case '\\': { if (len == 1) break; else in_buff[len-1] = 0; } default: { if (inside && check_filter(in_buff)) printf(" \\\n %s", in_buff); break; } } } printf("\n"); return 0; }
void loss(float f0, float fs, float c1, float c3, Filter *c) { c->n = 1; float g = 1.0 - c1/f0; float b = 4.0*c3+f0; float a1 = (-b+sqrt(b*b-16.0*c3*c3))/(4.0*c3); c->b[0] = g*(1+a1); c->b[1] = 0; c->a[0] = 1; c->a[1] = a1; init_filter(c); }
EKF::EKF(int _n, int _m, void (*_f_func)(MatrixXd&,MatrixXd&,VectorXd&,const VectorXd&, const float dt), void (*_h_func)(MatrixXd&,VectorXd&,const VectorXd&, const VectorXd&), void (*_c_func)(const VectorXd &, VectorXd &), float _q, float _r) { init_filter( _n, _m); f_func = _f_func; h_func = _h_func; c_func = _c_func; setQ(_q); setR(_r); }
static sliceable_switch * create_sliceable_switch( const char *topology_service, const switch_options *options ) { assert( topology_service != NULL ); assert( options != NULL ); // Allocate sliceable_switch object sliceable_switch *instance = xmalloc( sizeof( sliceable_switch ) ); instance->idle_timeout = options->idle_timeout; instance->handle_arp_with_packetout = options->handle_arp_with_packetout; instance->setup_reverse_flow = options->setup_reverse_flow; instance->switches = NULL; instance->fdb = NULL; instance->pathresolver = NULL; instance->second_stage_down = false; instance->last_stage_down = false; info( "idle_timeout is set to %u [sec].", instance->idle_timeout ); if ( instance->handle_arp_with_packetout ) { info( "Handle ARP with packetout" ); } // Create pathresolver table instance->pathresolver = create_pathresolver(); // Create forwarding database instance->fdb = create_fdb(); // Initialize port database instance->switches = create_ports( &instance->switches ); // Initialize libraries init_libtopology( topology_service ); // Ask topology manager to notify any topology change events. // after_subscribed() will be called subscribe_topology( after_subscribed, instance ); // Initialize filter init_filter( options->filter_db_file ); // Initialize multiple slices support init_slice( options->slice_db_file, options->mode, instance ); // Initialize redirector init_redirector(); return instance; }
void ATC_TransferThermal::initialize() { // Base class initalizations ATC_Transfer::initialize(); if (!timeFilterManager_.filter_dynamics()) { DENS_VEC atomicKineticEnergy(nLocal_); compute_atomic_kinetic_energy(atomicKineticEnergy, lammpsInterface_->vatom()); project_volumetric_quantity(atomicKineticEnergy,fieldNdFiltered_[TEMPERATURE],TEMPERATURE); fieldNdFiltered_[TEMPERATURE] *= 2.; } thermostat_.initialize(); extrinsicModelManager_.initialize(); if (!initialized_) { // initialize sources based on initial FE temperature double dt = lammpsInterface_->dt(); prescribedDataMgr_->set_sources(simTime_+.5*dt,sources_); extrinsicModelManager_.set_sources(fields_,extrinsicSources_); thermostat_.compute_boundary_flux(fields_); compute_atomic_sources(fieldMask_,fields_,atomicSources_); } if (timeFilterManager_.need_reset()) { init_filter(); timeFilterManager_.initialize(); } // reset integration field mask temperatureMask_.reset(NUM_FIELDS,NUM_FLUX); temperatureMask_ = false; for (int i = 0; i < NUM_FLUX; i++) temperatureMask_(TEMPERATURE,i) = fieldMask_(TEMPERATURE,i); initialized_ = true; if (pmfcOn_) { oldFieldTemp_.reset(nNodes_,1); } // read in field data if necessary if (useRestart_) { OUTPUT_LIST data; read_restart_data(restartFileName_,data); useRestart_ = false; } }
void thirian(float D, int N, Filter *c) { c->n = N; for(int k=0;k<=N;k++) { double ak = (float)choose((long)N,(long)k); if(k%2==1) ak = -ak; for(int n=0;n<=N;n++) { ak *= ((double)D-(double)(N-n)); ak /= ((double)D-(double)(N-k-n)); } c->a[k] = (float)ak; c->b[N-k] = (float)ak; } init_filter(c); }
void merge_filters(Filter *c1, Filter *c2, Filter *c) { int n = c1->n + c2->n; c->n = n; for(int j=0;j<=n;j++) { c->a[j] = 0; c->b[j] = 0; } for(int j=0;j<=c1->n;j++) { for(int k=0;k<=c2->n;k++) { c->a[j+k] += c1->a[j]*c2->a[k]; c->b[j+k] += c1->b[j]*c2->b[k]; } } init_filter(c); }
void thiriandispersion(float B, float f, int M, Filter *c) { int N = 2; float D; D = Db(B,f,M); if(D<=1.0) { c->n = 2; c->a[0] = 1; c->a[1] = 0; c->a[2] = 0; c->b[0] = 1; c->b[1] = 0; c->b[2] = 0; init_filter(c); } else { thirian(D,N,c); } }
void biquad(float f0, float fs, float Q, int type, Filter *c) { c->n = 2; float a = 1/(2*tan(PI*f0/fs)); float a2 = a*a; float aoQ = a/Q; float d = (4*a2+2*aoQ+1); c->a[0] = 1; c->a[1] = -(8*a2-2) / d; c->a[2] = (4*a2 - 2*aoQ + 1) / d; switch(type) { case pass: c->b[0] = 2*aoQ/d; c->b[1] = 0; c->b[2] = -2*aoQ/d; break; case low: c->b[0] = 1/d; c->b[1] = 2/d; c->b[2] = 1/d; break; case high: c->b[0] = 4*a2/d; c->b[1] = -8*a2/d; c->b[2] = 4*a2/d; break; case notch: c->b[0] = (1+4*a2)/d; c->b[1] = (2-8*a2)/d; c->b[2] = (1+4*a2)/d; break; } init_filter(c); }
/** * Opens the filter window with a new filter. * * @param nf defines the filter that should be added. The * object copied so the argument can be freed after calling * the function. */ void filter_open_with_new_filter(struct filter *nf) { struct filter *f; int new_active; if (!filter_wnd) { init_filter(); if (!filter_wnd) return; } filter_last_selected = NULL; /* Clear the filter listview contents */ DoMethod(filter_list, MUIM_NList_Clear); /* Add the filters to the list */ f = filter_list_first(); while (f) { DoMethod(filter_list, MUIM_NList_InsertSingle, (ULONG)f, MUIV_NList_Insert_Bottom); f = filter_list_next(f); } if (nf) { DoMethod(filter_list, MUIM_NList_InsertSingle, (ULONG)nf, MUIV_NList_Insert_Bottom); new_active = xget(filter_list,MUIA_NList_Entries)-1; } else { new_active = 0; } set(filter_list, MUIA_NList_Active, new_active); filter_active(); set(filter_wnd, MUIA_Window_Open, TRUE); }
static void init_time(enum time_type tt, char * pattern) { Filter * filter = init_filter(); struct time_info * ti = malloc(sizeof(struct time_info)); struct stat buf; ti->tt = tt; if (tt == ANEWER || tt == CNEWER || tt == MNEWER) { stat(pattern, &buf); time_t * time = (time_t *)malloc(sizeof(time_t)); if (tt == ANEWER) { *time = buf.st_atime; } else if (tt == CNEWER) { *time = buf.st_ctime; } else { *time = buf.st_mtime; } ti->value = time; } else { ti->value = pattern; } filter->info = ti; filter->ft = TIME_FILTER; filter->cmd = time_filter; push_op_stack(filter); }
int main(int argc, char** argv) { if (argc != 2) { printf("Usage: %s <iterations>\n", argv[0]); return (EXIT_FAILURE); } int iterations = atoi(argv[1]); printf("main_cuda()\n"); printf("Iterations: %d\n", iterations); bool ok = true; /* Read input file into buffer. */ unsigned char (**image_buffer_h)[CHANNELS]; if (ok) ok = read_image((unsigned char ***) &image_buffer_h); /* Allocate memory for image data. */ float (**image_h)[CHANNELS]; if (ok) ok = alloc_float_array((float ***) &image_h, B + HEIGHT + B, B + WIDTH + B, CHANNELS); /* Convert input. */ unsigned int i, j, c; if (ok) { for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) for (c = 0; c < CHANNELS; c++) image_h[i + B][j + B][c] = (float) image_buffer_h[i][j][c]; } /* Device memory allocation. */ float (**prev_image_d)[CHANNELS]; float (**curr_image_d)[CHANNELS]; float *prev_image_p; float *curr_image_p; if (ok) ok = alloc_float_array_cuda((float ***) &prev_image_d, &prev_image_p, B + HEIGHT + B, B + WIDTH + B, CHANNELS); if (ok) ok = alloc_float_array_cuda((float ***) &curr_image_d, &curr_image_p, B + HEIGHT + B, B + WIDTH + B, CHANNELS); /* Initialize filter in device memory space. */ float (**filter_d)[1]; float *filter_p; if (ok) ok = init_filter(&filter_d, &filter_p, filter); /* Device parameters for nVidia 9600GT (G94), passed to main filter function. */ /* nVidia G94 supports 8 resident blocks per SMP, 768 resident threads per SMP. */ unsigned int block_size = 64; // maximum 512 threads per block for nVidia G94 printf("Block size: %u\n", block_size); /* nVidia G94 supports 2-dimensional grids with a maximum of 65535 for x,y dimension. */ unsigned int grid_dim = HEIGHT * WIDTH / block_size; double sqr = sqrt(grid_dim); grid_dim = sqr; grid_dim++; printf("Grid: %ux%u\n", grid_dim, grid_dim); /* Start timing. */ float memcopy, compute; timestamp t_start; t_start = getTimestamp(); /* Copy image data to device. */ if (ok) ok = (cudaSuccess == cudaMemcpy(curr_image_p, &(image_h[0][0][0]), (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float), cudaMemcpyHostToDevice)); memcopy = getElapsedtime(t_start); /* Clear host image data. */ memset(&(image_h[0][0][0]), 0, (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float)); /* Apply filter. */ t_start = getTimestamp(); unsigned int n; if (ok) { for (n = 0; iterations == 0 || n < iterations; n++) { /* Fill borders with edge image data. */ fill_borders(curr_image_d, HEIGHT, WIDTH); /* Apply filter. */ apply_filter_cuda(prev_image_d, curr_image_d, filter_d, block_size, grid_dim); /* Switch current / previous image buffers. */ float (**temp)[CHANNELS]; temp = prev_image_d; prev_image_d = curr_image_d; curr_image_d = temp; float *tmp; tmp = prev_image_p; prev_image_p = curr_image_p; curr_image_p = tmp; } } /* Stop time measurement, print time. */ cudaThreadSynchronize(); compute = getElapsedtime(t_start); t_start = getTimestamp(); /* Copy processed image data from device. */ if (ok) ok = (cudaSuccess == cudaMemcpy(&(image_h[0][0][0]), curr_image_p, (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float), cudaMemcpyDeviceToHost)); memcopy += getElapsedtime(t_start); printf("Completed in %.3f sec\n", compute / 1000); printf("Memory copy in %.3f sec\n", memcopy / 1000); /* Convert output. */ if (ok) { for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) for (c = 0; c < CHANNELS; c++) image_buffer_h[i][j][c] = (unsigned char) image_h[i + B][j + B][c]; } /* Create output files, one for each channel. */ if (ok) ok = write_channels(image_buffer_h, HEIGHT, WIDTH); /* Free allocated memory. */ dealloc_uchar_array((unsigned char ***) &image_buffer_h); dealloc_float_array((float ***) &image_h); dealloc_float_array_cuda((float ***) &prev_image_d, &prev_image_p); dealloc_float_array_cuda((float ***) &curr_image_d, &curr_image_p); destroy_filter(&filter_d, &filter_p); return ok ? (EXIT_SUCCESS) : (EXIT_FAILURE); }
static void init_true() { Filter * filter = init_filter(); filter->ft = TRUE_FILTER; filter->cmd = true_filter; push_op_stack(filter); }
int main(int argc, char *argv[]) { int c, fd = 0, on = 1, out_fd = 0, peer, reqsize = 0; int transwait = DEFTRANSWAIT; char *p; struct tftphdr *tp; struct passwd *pw; size_t cbuflen; char *cbuf; char req[PKTSIZE]; struct cmsghdr *cmsg; struct msghdr msg; struct iovec iov; struct sockaddr_storage from, proxy, server, proxy_to_server, s_in; struct sockaddr_in sock_out; socklen_t j; in_port_t bindport; openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); while ((c = getopt(argc, argv, "vw:")) != -1) switch (c) { case 'v': verbose++; break; case 'w': transwait = strtoll(optarg, &p, 10); if (transwait < 1) { syslog(LOG_ERR, "invalid -w value"); exit(1); } break; default: usage(); break; } /* open /dev/pf */ init_filter(NULL, verbose); tzset(); pw = getpwnam(NOPRIV_USER); if (!pw) { syslog(LOG_ERR, "no such user %s: %m", NOPRIV_USER); exit(1); } if (chroot(CHROOT_DIR) || chdir("/")) { syslog(LOG_ERR, "chroot %s: %m", CHROOT_DIR); exit(1); } #ifdef __NetBSD__ if (setgroups(1, &pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid)) { syslog(LOG_ERR, "can't revoke privs: %m"); exit(1); } #else if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { syslog(LOG_ERR, "can't revoke privs: %m"); exit(1); } #endif /* !__NetBSD__ */ /* non-blocking io */ if (ioctl(fd, FIONBIO, &on) < 0) { syslog(LOG_ERR, "ioctl(FIONBIO): %m"); exit(1); } if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) == -1) { syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); exit(1); } j = sizeof(s_in); if (getsockname(fd, (struct sockaddr *)&s_in, &j) == -1) { syslog(LOG_ERR, "getsockname: %m"); exit(1); } bindport = ((struct sockaddr_in *)&s_in)->sin_port; /* req will be pushed back out at the end, unchanged */ j = sizeof(from); if ((reqsize = recvfrom(fd, req, sizeof(req), MSG_PEEK, (struct sockaddr *)&from, &j)) < 0) { syslog(LOG_ERR, "recvfrom: %m"); exit(1); } bzero(&msg, sizeof(msg)); iov.iov_base = req; iov.iov_len = sizeof(req); msg.msg_name = &from; msg.msg_namelen = sizeof(from); msg.msg_iov = &iov; msg.msg_iovlen = 1; cbuflen = CMSG_SPACE(sizeof(struct sockaddr_storage)); if ((cbuf = malloc(cbuflen)) == NULL) { syslog(LOG_ERR, "malloc: %m"); exit(1); } msg.msg_control = cbuf; msg.msg_controllen = cbuflen; if (recvmsg(fd, &msg, 0) < 0) { syslog(LOG_ERR, "recvmsg: %m"); exit(1); } close(fd); close(1); peer = socket(from.ss_family, SOCK_DGRAM, 0); if (peer < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } memset(&s_in, 0, sizeof(s_in)); s_in.ss_family = from.ss_family; s_in.ss_len = from.ss_len; /* get local address if possible */ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { memcpy(&((struct sockaddr_in *)&s_in)->sin_addr, CMSG_DATA(cmsg), sizeof(struct in_addr)); break; } } if (bind(peer, (struct sockaddr *)&s_in, s_in.ss_len) < 0) { syslog(LOG_ERR, "bind: %m"); exit(1); } if (connect(peer, (struct sockaddr *)&from, from.ss_len) < 0) { syslog(LOG_ERR, "connect: %m"); exit(1); } tp = (struct tftphdr *)req; if (!(ntohs(tp->th_opcode) == RRQ || ntohs(tp->th_opcode) == WRQ)) { /* not a tftp request, bail */ if (verbose) { syslog(LOG_WARNING, "not a valid tftp request"); exit(1); } else /* exit 0 so inetd doesn't log anything */ exit(0); } j = sizeof(struct sockaddr_storage); if (getsockname(fd, (struct sockaddr *)&proxy, &j) == -1) { syslog(LOG_ERR, "getsockname: %m"); exit(1); } ((struct sockaddr_in *)&proxy)->sin_port = bindport; /* find the un-rdr'd server and port the client wanted */ if (server_lookup((struct sockaddr *)&from, (struct sockaddr *)&proxy, (struct sockaddr *)&server, IPPROTO_UDP) != 0) { syslog(LOG_ERR, "pf connection lookup failed (no rdr?)"); exit(1); } /* establish a new outbound connection to the remote server */ if ((out_fd = socket(((struct sockaddr *)&from)->sa_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) { syslog(LOG_ERR, "couldn't create new socket"); exit(1); } bzero((char *)&sock_out, sizeof(sock_out)); sock_out.sin_family = from.ss_family; sock_out.sin_port = htons(pick_proxy_port()); if (bind(out_fd, (struct sockaddr *)&sock_out, sizeof(sock_out)) < 0) { syslog(LOG_ERR, "couldn't bind to new socket: %m"); exit(1); } if (connect(out_fd, (struct sockaddr *)&server, ((struct sockaddr *)&server)->sa_len) < 0 && errno != EINPROGRESS) { syslog(LOG_ERR, "couldn't connect to remote server: %m"); exit(1); } j = sizeof(struct sockaddr_storage); if ((getsockname(out_fd, (struct sockaddr *)&proxy_to_server, &j)) < 0) { syslog(LOG_ERR, "getsockname: %m"); exit(1); } if (verbose) syslog(LOG_INFO, "%s:%d -> %s:%d/%s:%d -> %s:%d \"%s %s\"", sock_ntop((struct sockaddr *)&from), ntohs(((struct sockaddr_in *)&from)->sin_port), sock_ntop((struct sockaddr *)&proxy), ntohs(((struct sockaddr_in *)&proxy)->sin_port), sock_ntop((struct sockaddr *)&proxy_to_server), ntohs(((struct sockaddr_in *)&proxy_to_server)->sin_port), sock_ntop((struct sockaddr *)&server), ntohs(((struct sockaddr_in *)&server)->sin_port), opcode(ntohs(tp->th_opcode)), tp->th_stuff); /* get ready to add rdr and pass rules */ if (prepare_commit(1) == -1) { syslog(LOG_ERR, "couldn't prepare pf commit"); exit(1); } /* rdr from server to us on our random port -> client on its port */ if (add_rdr(1, (struct sockaddr *)&server, (struct sockaddr *)&proxy_to_server, ntohs(sock_out.sin_port), (struct sockaddr *)&from, ntohs(((struct sockaddr_in *)&from)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add rdr"); exit(1); } /* explicitly allow the packets to return back to the client (which pf * will see post-rdr) */ if (add_filter(1, PF_IN, (struct sockaddr *)&server, (struct sockaddr *)&from, ntohs(((struct sockaddr_in *)&from)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add pass in"); exit(1); } if (add_filter(1, PF_OUT, (struct sockaddr *)&server, (struct sockaddr *)&from, ntohs(((struct sockaddr_in *)&from)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add pass out"); exit(1); } /* and just in case, to pass out from us to the server */ if (add_filter(1, PF_OUT, (struct sockaddr *)&proxy_to_server, (struct sockaddr *)&server, ntohs(((struct sockaddr_in *)&server)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add pass out"); exit(1); } if (do_commit() == -1) { syslog(LOG_ERR, "couldn't commit pf rules"); exit(1); } /* forward the initial tftp request and start the insanity */ if (send(out_fd, tp, reqsize, 0) < 0) { syslog(LOG_ERR, "couldn't forward tftp packet: %m"); exit(1); } /* allow the transfer to start to establish a state */ sleep(transwait); /* delete our rdr rule and clean up */ prepare_commit(1); do_commit(); return(0); }