Пример #1
0
void rip_incoming(ssize_t n)
/* Use a RIP packet to add to the router table.  (RIP packets are really for
 * between routers, but often it is the only information around.)
 */
{
	udp_io_hdr_t *udp_io_hdr;
	u32_t default_dist;
	i32_t pref;
	routeinfo_t *routeinfo;
	struct routedata *data, *end;

	/* We don't care about RIP packets when there are router adverts. */
	if (now + MaxAdvertisementInterval < router_advert_valid) return;

	udp_io_hdr= (udp_io_hdr_t *) rip_buf;
	if (udp_io_hdr->uih_data_len != n - sizeof(*udp_io_hdr)) {
		if (debug) printf("Bad sized route packet (discarded)\n");
		return;
	}
	routeinfo= (routeinfo_t *) (rip_buf + sizeof(*udp_io_hdr)
			+ udp_io_hdr->uih_ip_opt_len);

	if (routeinfo->command != RIP_REPLY) {
		if (debug) {
			printf("RIP-%d packet command %d ignored\n",
				routeinfo->version, routeinfo->command);
		}
		return;
	}

	/* Look for a default route, the route to the gateway. */
	end= (struct routedata *) (rip_buf + n);
	default_dist= (u32_t) -1;
	for (data= routeinfo->data; data < end; data++) {
		if (ntohs(data->family) != AF_INET || data->ip_addr != 0)
			continue;
		default_dist= ntohl(data->metric);
		if (default_dist >= 256) {
			if (debug) {
				printf("Strange metric %lu\n",
					(unsigned long) default_dist);
			}
		}
	}
	pref= default_dist >= 256 ? 1 : 512 - default_dist;
	pref+= priority_offset;

	/* Add the gateway to the table with the calculated preference. */
	add_gateway(udp_io_hdr->uih_src_addr, pref);

	if (debug) {
		printf("Routing table after RIP-%d packet from %s:\n",
			routeinfo->version,
			addr2name(udp_io_hdr->uih_src_addr));
		print_table();
	}

	/* Start advertizing. */
	if (next_advert == NEVER) next_advert= IMMEDIATELY;
}
Пример #2
0
/* ------------------------------------------------------------- **
**  Sets up the control connection to the server and initialises
**  session info.
** ------------------------------------------------------------- */
void init_session(int fd, struct sockaddr_in source)
{
	info = init_info(fd, source);

	write_log(INFO, "Connect from %s",
		  sstr_buf(addr2name(info->client_control.address.sin_addr)));

	/*FIXME have a login function which deals with ntp and cache */
	ccp_changedest();
	ntp_changedest();
	info->final_server_address = info->server_control.address;

	write_log(INFO, "... to %s(%s)",
		  inet_ntoa(info->final_server_address.sin_addr),
		  sstr_buf(info->server_name));

#ifdef ENABLE_CHANGEPROC
	set_proc_title("frox: %s <-> %s",
		       inet_ntoa(info->client_control.address.sin_addr),
		       inet_ntoa(info->final_server_address.sin_addr));
#endif
	connect_to_server();

	ntp_senduser();

	run_proxy();
}
Пример #3
0
void
__cyg_profile_func_enter (void *func, void *caller) {
    if(profiled_func == NULL) {
        sprintf(buffer, "%p", func);
        addr2name(buffer);
        buffer[strlen(buffer)-1] = '\0';

        if(strcmp(buffer, target_function) == 0) {
            profiled_func = func;
        } else {
            return;
        }
    }

    if(profiled_func == func) {
        out = malloc(sizeof(struct data));
        out->func = profiled_func;
        out->caller = caller;

        gettimeofday( &current_time, NULL);

        out->sec = current_time.tv_sec;
        out->usec = current_time.tv_usec;
        out->state = 0;
        out->next = NULL;

        if(start == NULL) {
            start = out;
            last = out;
        } else {
            last->next = out;
            last = out;
        }
    }
}
Пример #4
0
void advertize(ipaddr_t host)
/* Send a router advert to a host. */
{
	char *buf, *data;
	ip_hdr_t *ip_hdr;
	icmp_hdr_t *icmp_hdr;
	int i;
	table_t *ptab;

	buf= malloc(sizeof(*ip_hdr) + offsetof(icmp_hdr_t, ih_dun.uhd_data)
			+ table_size * (sizeof(ipaddr_t) + sizeof(u32_t)));
	if (buf == nil) fatal("heap error");

	ip_hdr= (ip_hdr_t *) buf;
	icmp_hdr= (icmp_hdr_t *) (ip_hdr + 1);

	ip_hdr->ih_vers_ihl= 0x45;
	ip_hdr->ih_dst= host;

	icmp_hdr->ih_type= ICMP_TYPE_ROUTER_ADVER;
	icmp_hdr->ih_code= 0;
	icmp_hdr->ih_hun.ihh_ram.iram_na= 0;
	icmp_hdr->ih_hun.ihh_ram.iram_aes= 2;
	icmp_hdr->ih_hun.ihh_ram.iram_lt= htons(AdvertisementLifetime);
	data= (char *) icmp_hdr->ih_dun.uhd_data;

	/* Collect gateway entries from the table. */
	for (i= 0, ptab= table; i < table_size; i++, ptab++) {
		if (ptab->tab_time < now - DEAD_TO) continue;

		icmp_hdr->ih_hun.ihh_ram.iram_na++;
		if (ptab->tab_time < now - DEST_TO) ptab->tab_pref= DEAD_PREF;
		* (ipaddr_t *) data= ptab->tab_gw;
		data+= sizeof(ipaddr_t);
		* (i32_t *) data= htonl(ptab->tab_pref);
		data+= sizeof(i32_t);
	}
	icmp_hdr->ih_chksum= 0;
	icmp_hdr->ih_chksum= ~oneC_sum(0, icmp_hdr, data - (char *) icmp_hdr);

	if (icmp_hdr->ih_hun.ihh_ram.iram_na > 0) {
		/* Send routing info. */

		if (debug) {
			printf("Routing table send to %s:\n", addr2name(host));
			print_table();
		}

		if (write(irdp_fd, buf, data - buf) < 0) {
			(errno == EIO ? fatal : report)(ip_device);
		}
	}
	free(buf);
}
Пример #5
0
/*
 *                           u_accept
 * Wait for a connection request from a host on a specified port.
 *
 * parameters:
 *      fd = file descriptor previously bound to listening port
 *      hostn = a buffer that will hold the name of the remote host
 *      hostnsize = size of hostn buffer
 * returns:  a communication file descriptor on success
 *              hostn is filled with the name of the remote host.
 *           -1 on error with errno set
 *
 * comments: This function is used by the server to wait for a
 * communication.  It blocks until a remote request is received
 * from the port bound to the given file descriptor.
 * hostn is filled with an ASCII string containing the remote
 * host name.  It must point to a buffer of size at least hostnsize.
 * If the name does not fit, as much of the name as is possible is put
 * into the buffer.
 * If hostn is NULL or hostnsize <= 0, no hostname is copied.
 */
int u_accept(int fd, char *hostn, int hostnsize) {
   int len = sizeof(struct sockaddr);
   struct sockaddr_in netclient;
   int retval;

   while (((retval =
           accept(fd, (struct sockaddr *)(&netclient), &len)) == -1) &&
          (errno == EINTR))
      ;
   if ((retval == -1) || (hostn == NULL) || (hostnsize <= 0))
      return retval;
   addr2name(netclient.sin_addr, hostn, hostnsize);
   return retval;
}
Пример #6
0
void print_table(void)
/* Show the collected routing table. */
{
	int i;
	table_t *ptab;
	struct tm *tm;

	for (i= 0, ptab= table; i < table_size; i++, ptab++) {
		if (ptab->tab_time < now - DEAD_TO) continue;

		tm= localtime(&ptab->tab_time);
		printf("%-40s %6ld %02d:%02d:%02d\n",
			addr2name(ptab->tab_gw),
			(long) ptab->tab_pref,
			tm->tm_hour, tm->tm_min, tm->tm_sec);
	}
}
Пример #7
0
void __attribute__((optimize("O0"))) panic(char* error, ...) {
	if(unlikely(!spinlock_get(&lock, 30))) {
		freeze();
	}

	va_list va;
	va_start(va, error);
	interrupts_disable();

	panic_printf("\nKernel Panic: ");
	vprintf(error, va);
	serial_vprintf(error, va);
	panic_printf("\n");
	va_end(va);

	panic_printf("Last PIT tick:   %d (rate %d, uptime: %d seconds)\n",
		(uint32_t)timer_tick, timer_rate, uptime());

	task_t* task = scheduler_get_current();
	if(task) {
		panic_printf("Running task:    %d <%s>", task->pid, task->name);

	/*	uint32_t task_offset = task->state->eip - task->entry;
		if(task_offset >= 0) {
			panic_printf("+%x at 0x%x", task_offset, task->state->eip);
		}
*/
		panic_printf("\n");
	} else {
		panic_printf("Running task:    [No task running]\n");
	}

	panic_printf("Paging context:  %s\n\n", vmem_get_name(vmem_currentContext));
	panic_printf("Call trace:\n");
	intptr_t addresses[10];
	int read = walk_stack(addresses, 10);

	for(int i = 0; i < read; i++) {
		panic_printf("#%-6d %s <%#x>\n", i, addr2name(addresses[i]), addresses[i]);
	}

	freeze();
}
Пример #8
0
/* Print the symbol address => name resolution table in $TRACY_ASYNC mode. */
static void resolve_backlog(void)
{
	void *addr;

	/* A lot of entries will be duplicate but nevermind. */
	LOGIT("SYMTAB:");
	lseek(Async_fd, SEEK_SET, 0);
	while (read(Async_fd, &addr, sizeof(addr)) == sizeof(addr))
	{
		char const *fname, *funame;

		switch (addr2name(&fname, &funame, addr))
		{
		case 1:
			LOGIT("%p = %s:%s()", addr, fname, funame);
			break;
		case 0:
			LOGIT("%p = %s:[%p]", addr, fname, addr);
			break;
		}
	}
	close(Async_fd);
}
Пример #9
0
void irdp_incoming(ssize_t n)
/* Look for router solicitations and router advertisements.  The solicitations
 * are probably from other irdpd daemons, we answer them if we do not expect
 * a real router to answer.  The advertisements cause this daemon to shut up.
 */
{
	ip_hdr_t *ip_hdr;
	icmp_hdr_t *icmp_hdr;
	int ip_hdr_len;
	char *data;
	int i;
	int router;
	ipaddr_t addr;
	i32_t pref;
	time_t valid;

	ip_hdr= (ip_hdr_t *) irdp_buf;
	ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;
	if (n < ip_hdr_len + 8) {
		if (debug) printf("Bad sized ICMP (discarded)\n");
		return;
	}

	icmp_hdr= (icmp_hdr_t *)(irdp_buf + ip_hdr_len);

	/* Did I send this myself? */
	if (ip_hdr->ih_src == ip_hdr->ih_dst) return;
	if ((htonl(ip_hdr->ih_src) & 0xFF000000L) == 0x7F000000L) return;

	if (icmp_hdr->ih_type != ICMP_TYPE_ROUTER_ADVER) return;

	/* Incoming router advertisement, the kind of packet the TCP/IP task
	 * is very happy with.  No need to solicit further.
	 */
	sol_retries= 0;

	/* Add router info to our table.  Also see if the packet really came
	 * from a router.  If so then we can go dormant for the lifetime of
	 * the ICMP.
	 */
	router= 0;
	data= (char *) icmp_hdr->ih_dun.uhd_data;
	for (i= 0; i < icmp_hdr->ih_hun.ihh_ram.iram_na; i++) {
		addr= * (ipaddr_t *) data;
		data+= sizeof(ipaddr_t);
		pref= htonl(* (i32_t *) data);
		data+= sizeof(i32_t);

		if (addr == ip_hdr->ih_src) {
			/* The sender is in the routing table! */
			router= 1;
		}
		add_gateway(addr, pref);
	}

	valid= now + ntohs(icmp_hdr->ih_hun.ihh_ram.iram_lt);
	if (router) router_advert_valid= valid;

	/* Restart advertizing close to the timeout of the advert.  (No more
	 * irdpd adverts if the router stays alive.)
	 */
	if (router || next_advert > valid - DANGER)
		next_advert= valid - DANGER;

	if (debug) {
		printf("Routing table after advert received from %s:\n",
			addr2name(ip_hdr->ih_src));
		print_table();
		if (router) {
			struct tm *tm= localtime(&router_advert_valid);
			printf(
			"This router advert is valid until %02d:%02d:%02d\n",
				tm->tm_hour, tm->tm_min, tm->tm_sec);
		}
	}
}
Пример #10
0
/*
 * Show collected CPU/DSP callee/caller information.
 *
 * Hint: As caller info list is based on number of loaded symbols,
 * load only text symbols to save memory & make things faster...
 */
void Profile_ShowCallers(FILE *fp, int sites, callee_t *callsite, const char * (*addr2name)(Uint32, Uint64 *))
{
	int i, j, countissues, countdiff;
	const char *name;
	caller_t *info;
	Uint64 total;
	Uint32 addr, typeaddr;

	/* legend */
	fputs("# <callee>: <caller1> = <calls> <types>[ <inclusive/totals>[ <exclusive/totals>]], <caller2> ..., <callee name>", fp);
	fputs("\n# types: ", fp);
	for (i = 0; i < ARRAYSIZE(flaginfo); i++) {
		fprintf(fp, "%c = %s, ", flaginfo[i].chr, flaginfo[i].info);
	}
	fputs("\n# totals: calls/instructions/cycles/misses\n", fp);

	countdiff = 0;
	countissues = 0;
	for (i = 0; i < sites; i++, callsite++) {
		addr = callsite->addr;
		if (!addr) {
			continue;
		}
		name = addr2name(addr, &total);
		fprintf(fp, "0x%x: ", callsite->addr);

		typeaddr = 0;
		info = callsite->callers;
		qsort(info, callsite->count, sizeof(*info), cmp_callers);
		for (j = 0; j < callsite->count; j++, info++) {
			if (!info->calls) {
				break;
			}
			total -= info->calls;
			output_caller_info(fp, info, &typeaddr);
		}
		if (name) {
			fprintf(fp, "%s", name);
		}
		fputs("\n", fp);
		if (total) {
#if DEBUG
			fprintf(stderr, "WARNING: %llu differences in call and instruction counts for '%s'!\n", total, name);
#endif
			countdiff += total;
			countissues++;
		}
		if (typeaddr) {
			fprintf(stderr, "WARNING: different types of calls (at least) from 0x%x (to 0x%x),\n\t has its codechanged during profiling?\n",
				typeaddr, callsite->addr);
		}
	}
	if (countissues) {
		if (countdiff <= 2 && countissues == countdiff) {
			fprintf(stderr, "WARNING: callcount mismatches (%d calls) with address instruction\n\t counts in %d cases, most likely profile start & end.\n",
				countdiff, countissues);
		} else {
			/* profiler bug: some (address?) mismatch in recording instruction counts and call counts */
			fprintf(stderr, "ERROR: callcount mismatches with address instruction counts\n\t(%d in total) detected in %d cases!\n",
				countdiff, countissues);
		}
	}
}
Пример #11
0
/* Determines which function the control flow entered/left
 * and prints the trace message. */
static int print_trace(void *addr, char const *dir)
{
	static unsigned depth_limit;
	static int depth_limited = -1, be_async = -1, entries_only = -1;
	static int indent = -1, log_fname = -1;
	char const *env, *colon, *fname, *funame;
	int is_entry, success;

	/* Read $TRACY_MAXDEPTH if we haven't. */
	if (depth_limited < 0)
	{
		if ((env = getenv("TRACY_MAXDEPTH")) && env[0])
		{
			depth_limit = atoi(env);
			depth_limited = 1;
		} else
			depth_limited = 0;
	}

	/* Have we reached the limit? */
	if (depth_limited && Callstack_depth >= depth_limit)
		return 1;

#ifndef __ARMEL__
	{
		void *addrs[3];

		/*
		 * In the frame:
		 * [0] this function,
		 * [1] the instrumentation function,
		 * [2] the function we're interested in.
		 *
		 * On ARM backtrace() is unreliable, so use $addr directly.
		 * On x86 we can't avoid this call.
		 */
		if (backtrace(addrs, 3) < 3)
			return 1;
		addr = addrs[2];
	}
#endif /* ! __ARMEL__ */

	/* In async mode create a temporary file where we can write symbol
	 * addresses the program encounters on function calls enters. */
	if (be_async < 0)
	{
		be_async = (env = getenv("TRACY_ASYNC")) && env[0] == '1';
		if (be_async)
		{
			static char tmpfname[] = "/tmp/tracy.XXXXXX";

			if ((Async_fd = mkstemp(tmpfname)) < 0)
			{
				LOGIT("mkstemp: %m");
				be_async = 0;
			} else
			{
				unlink(tmpfname);
				atexit(resolve_backlog);
			}
		}
	} /* be_async? */

	/* Log only function entries? */
	is_entry = dir[0] == 'E';
	if (entries_only < 0)
		entries_only = (env = getenv("TRACY_LOG_ENTRIES_ONLY"))
			&& env[0] == '1';
	if (entries_only)
		dir = "";

	/* Get how much to indent $fname:$funame. */
	if (indent < 0)
		indent = (env = getenv("TRACY_LOG_INDENT")) ? atoi(env) : 0;

	/* Write the async file if necessary. */
	if (Async_fd >= 0)
	{	/* resolve_backlog() will resolve $addr when we exit. */
		if (!entries_only || is_entry)
			LOGIT("%s%s[%u]%*s[%p]", procinfo(), dir,
				Callstack_depth,
				1 + indent*Callstack_depth, " ", addr);
		if (is_entry)
			/* Try not to bloat the file, it'll have
			 * lots of identical entries anyway. */
			write(Async_fd, &addr, sizeof(addr));
		return 1;
	}

	/* Resolve $addr. */
	if ((success = addr2name(&fname, &funame, addr)) < 0)
		/* Omitted from output, don't count it in $Callstack_depth. */
		return 0;

	/* Don't log LEAVE:s if $entries_only. */
	if (entries_only && !is_entry)
		return 1;

	/* Print or omit the "<$fname>:" in front of $funame? */
	if (log_fname < 0)
		log_fname = (env = getenv("TRACY_LOG_FNAME")) ? env[0] == '1' : 1;
	if (log_fname)
		colon = ":";
	else
		fname = colon = "";

	/* Log the damn thing. */
	if (success)
		LOGIT("%s%s[%u]%*s%s%s%s()", procinfo(),
			dir, Callstack_depth, 1 + indent*Callstack_depth, " ",
			fname, colon, funame);
	else
		LOGIT("%s%s[%u]%*s%s%s[%p]", procinfo(),
			dir, Callstack_depth, 1 + indent*Callstack_depth, " ",
			fname, colon, addr);

	/* We've logged something. */
	return 1;
} /* print_trace */
Пример #12
0
static void connect_to_server(void)
{
	/*Check for loops. Won't work if Listen undefined */
	if(info->server_control.address.sin_addr.s_addr
	   == config.listen_address.sin_addr.s_addr &&
	   info->server_control.address.sin_port
	   == config.listen_address.sin_port)
		die(ERROR, "Attempt to connect to self. "
		    "Do you need to set DoNTP to yes?",
		    421, "Proxy tried to loop. Closing connection", 0);
	if(info->server_control.address.sin_addr.s_addr == 0) {
		if(!config.ntp)
			die(ERROR,
			    "Frox unable to determine destination address. "
			    "Do you need to set DoNTP to yes?",
			    501, "Unable to contact server", 0);
		else if(config.ntpdest.sin_addr.s_addr)
			die(ERROR,
			    "Frox unable to determine destination address. "
			    "Try commenting out NTPAddress",
			    501, "Unable to contact server", 0);
		else
			die(ERROR,
			    "Frox unable to determine detination address. "
			    "See FAQ for troubleshooting.", 501,
			    "Unable to contact server", 0);
	}

	resolve_addr(&info->final_server_address.sin_addr, info->server_name);

	if(!config_connectionok(&info->client_control.address,
				&info->final_server_address,
				info->username ? sstr_buf(info->
							  username) : 0))
		die(ATTACK, "Denied by ACLs.", 501, "Connection denied. Bye",
		    0);

	if(config.ftpproxy.sin_addr.s_addr)
		info->server_control.address = config.ftpproxy;

	write_log(VERBOSE, "Connecting to server...");

	info->server_control.fd =
		connect_to_socket(&info->server_control.address,
				  &config.tcpoutaddr, config.contports);

	if(info->server_control.fd == -1)
		die(ERROR, "Connection closed -- unable to contact server",
		    501, "Proxy unable to contact ftp server", 0);

	write_log(VERBOSE, "     OK");

	if(config.loglevel >= VERBOSE) {	/*Save the overhead of DNS lookups */
		write_log(VERBOSE, "Apparent address = %s",
			  sstr_buf(addr2name
				   (info->apparent_server_address.sin_addr)));
		write_log(VERBOSE, "Real address = %s",
			  sstr_buf(addr2name
				   (info->final_server_address.sin_addr)));
		write_log(VERBOSE, "Proxy address = %s",
			  sstr_buf(addr2name
				   (info->server_control.address.sin_addr)));
	}
	ssl_init();
}
Пример #13
0
void u_gethostname(u_buf_t *ubufp, char *hostn, int hostnsize) {
   struct sockaddr_in *remotep;

   remotep = (struct sockaddr_in *)ubufp;
   addr2name(remotep->sin_addr, hostn, hostnsize);
}