Beispiel #1
0
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++;
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
    }
Beispiel #9
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);
}
Beispiel #10
0
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);
    }
}
Beispiel #12
0
/**
 * 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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
	
}
Beispiel #15
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;
}
Beispiel #17
0
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; 
}
Beispiel #18
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);
}
Beispiel #19
0
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;
}
Beispiel #21
0
  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;
    }
  }
Beispiel #22
0
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);
}
Beispiel #23
0
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);
}
Beispiel #24
0
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);
  }
}
Beispiel #25
0
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);
}
Beispiel #26
0
/**
 * 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);
}
Beispiel #27
0
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);
}
Beispiel #28
0
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);
}
Beispiel #29
0
static void init_true() {
  Filter * filter = init_filter();
  filter->ft = TRUE_FILTER;
  filter->cmd = true_filter;
  push_op_stack(filter);
}
Beispiel #30
0
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);
}