/*
 * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *		Axel Dörfler, axeld@pinc-software.de
 *		James Woodcock
 */
 
#include <arpa/inet.h>
#include <errno.h>
#include <getopt.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
#include <SupportDefs.h>
 
#include <net_stat.h>
#include <syscalls.h>
 
 
extern const char* __progname;
const char* kProgramName = __progname;
 
static int sResolveNames = 1;
 
struct address_family {
	int			family;
	const char*	name;
	const char*	identifiers[4];
	void		(*print_address)(sockaddr* address);
};
 
// AF_INET family
static void inet_print_address(sockaddr* address);
 
static const address_family kFamilies[] = {
	{
		AF_INET,
		"inet",
		{"AF_INET", "inet", "ipv4", NULL},
		inet_print_address
	},
	{ -1, NULL, {NULL}, NULL }
};
 
 
static void
inet_print_address(sockaddr* _address)
{
	sockaddr_in& address = *(sockaddr_in *)_address;
 
	if (address.sin_family != AF_INET || address.sin_len == 0) {
		printf("%-22s", "-");
		return;
	}
 
	hostent* host = NULL;
	servent* service = NULL;
	if (sResolveNames) {
		host = gethostbyaddr((const char*)&address.sin_addr, sizeof(in_addr),
			AF_INET);
		service = getservbyport(address.sin_port, NULL);
	}
 
	const char *hostName;
	if (host != NULL)
		hostName = host->h_name;
	else if (address.sin_addr.s_addr == INADDR_ANY)
		hostName = "*";
	else
		hostName = inet_ntoa(address.sin_addr);
 
	char buffer[128];
	int length = strlcpy(buffer, hostName, sizeof(buffer));
 
	char port[64];
	if (service != NULL)
		strlcpy(port, service->s_name, sizeof(port));
	else if (address.sin_port == 0)
		strcpy(port, "*");
	else
		snprintf(port, sizeof(port), "%u", ntohs(address.sin_port));
 
	snprintf(buffer + length, sizeof(buffer) - length, ":%s", port);
 
	printf("%-22s", buffer);
}
 
 
//	#pragma mark -
 
 
void
usage(int status)
{
	printf("usage: %s [-nh]\n", kProgramName);
	printf("options:\n");
	printf("	-n	don't resolve names\n");
	printf("	-h	this help\n");
 
	exit(status);
}
 
 
bool
get_address_family(const char* argument, int32& familyIndex)
{
	for (int32 i = 0; kFamilies[i].family >= 0; i++) {
		for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
			if (!strcmp(argument, kFamilies[i].identifiers[j])) {
				// found a match
				familyIndex = i;
				return true;
			}
		}
	}
 
	// defaults to AF_INET
	familyIndex = 0;
	return false;
}
 
 
//	#pragma mark -
 
 
int
main(int argc, char** argv)
{
	int optionIndex = 0;
	int opt;
	static struct option longOptions[] = {
		{"help", no_argument, 0, 'h'},
		{"numeric", no_argument, 0, 'n'},
		{0, 0, 0, 0}
	};
 
	do {
		opt = getopt_long(argc, argv, "hn", longOptions, &optionIndex);
		switch (opt) {
			case -1:
				// end of arguments, do nothing
				break;
 
			case 'n':
				sResolveNames = 0;
				break;
 
			case 'h':
			default:
				usage(0);
				break;
		}
	} while (opt != -1);
 
	bool printProgram = true;
		// TODO: add some more program options... :-)
 
	printf("Proto  Recv-Q Send-Q Local Address         Foreign Address       "
		"State        Program\n");
 
	uint32 cookie = 0;
	int family = -1;
	net_stat stat;
	while (_kern_get_next_socket_stat(family, &cookie, &stat) == B_OK) {
		protoent* proto = getprotobynumber(stat.protocol);
		if (proto != NULL)
			printf("%-6s ", proto->p_name);
		else
			printf("%-6d ", stat.protocol);
 
		printf("%6lu ", stat.receive_queue_size);
		printf("%6lu ", stat.send_queue_size);
 
		inet_print_address((sockaddr*)&stat.address);
		inet_print_address((sockaddr*)&stat.peer);
		printf("%-12s ", stat.state);
 
		team_info info;
		if (printProgram && get_team_info(stat.owner, &info) == B_OK) {
			// remove arguments
			char* name = strchr(info.args, ' ');
			if (name != NULL)
				name[0] = '\0';
 
			// remove path name
			name = strrchr(info.args, '/');
			if (name != NULL)
				name++;
			else
				name = info.args;
 
			printf("%ld/%s\n", stat.owner, name);
		} else
			printf("%ld\n", stat.owner);
	}
 
	return 0;
}
 

↑ V576 Incorrect format. Consider checking the second actual argument of the 'printf' function. The memsize type argument is expected.

↑ V576 Incorrect format. Consider checking the second actual argument of the 'printf' function. The memsize type argument is expected.