/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <fcntl.h>
#include <stdlib.h>
#include <strings.h>
#include <exacct.h>
#include <sys/ethernet.h>
#include <libdladm.h>
(step) = 1; \
(tbytes) = 0; \
(ttime) = 0; \
(tibytes) = 0; \
(tobytes) = 0; \
}
typedef struct net_desc_s {
} net_desc_t;
/* Time structure: Year, Month, Day, Hour, Min, Sec */
typedef struct net_time_s {
int net_time_yr;
int net_time_mon;
int net_time_day;
int net_time_hr;
int net_time_min;
int net_time_sec;
} net_time_t;
typedef struct net_stat_s {
} net_stat_t;
/* Used to create the [gnu]plot file */
typedef struct net_plot_entry_s {
char *net_pe_name;
/* Stats entry */
typedef struct net_entry_s {
int net_entry_scount;
} net_entry_t;
/* Time sorted list */
typedef struct net_time_entry_s {
/* The parsed table */
typedef struct net_table_s {
/* List of stats */
int net_entries;
/*
* Optimization I : List sorted by time, i.e:
* Time Resource ..
* -------------------------------
* 11.15.10 bge0
* 11.15.10 ce0
* 11.15.10 vnic1
* 11.15.15 bge0
* 11.15.15 ce0
* 11.15.15 vnic1
*/
/*
* Optimization II : List sorted by resources
* Time Resource ..
* -------------------------------
* 11.15.10 bge0
* 11.15.15 bge0
* 11.15.10 ce0
* 11.15.15 ce0
* 11.15.10 vnic1
* 11.15.15 vnic1
*/
/* Common to both the above (sorted) lists. */
int net_time_entries;
} net_table_t;
#define NET_DATE_GREATER 0
#define NET_TIME_GREATER 0
#ifndef _LP64
#else
#endif
/*
* Given a timebuf of the form M/D/Y,H:M:S break it into individual elements.
*/
static void
{
char *d;
char *t;
char *dd;
char *h;
char *endp;
return;
/* Month */
return;
/* Day */
return;
/* Year */
return;
if (t == NULL)
return;
/* Hour */
h = strtok(t, ":");
if (h == NULL)
return;
/* Min */
if (h == NULL)
return;
/* Sec */
if (h == NULL)
return;
}
/* Get a stat item from an object in the exacct file */
static void
{
switch (o->eo_catalog & EXT_TYPE_MASK) {
case EXT_STRING:
}
break;
case EXT_UINT64:
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
}
break;
default:
break;
}
}
/* Get a description item from an object in the exacct file */
static void
{
switch (o->eo_catalog & EXT_TYPE_MASK) {
case EXT_STRING:
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
}
break;
case EXT_UINT8:
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
}
break;
case EXT_UINT16:
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
}
break;
case EXT_UINT32:
if ((o->eo_catalog & EXD_DATA_MASK) ==
&nd->net_desc_saddr);
} else {
&nd->net_desc_daddr);
}
}
break;
case EXT_UINT64:
break;
case EXT_RAW:
if ((o->eo_catalog & EXD_DATA_MASK) ==
} else {
}
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
} else if ((o->eo_catalog & EXD_DATA_MASK) ==
}
break;
default:
break;
}
}
/* Add a description item to the table */
static dladm_status_t
{
return (DLADM_STATUS_NOMEM);
return (DLADM_STATUS_NOMEM);
}
ne->net_entry_scount = 0;
} else {
}
net_table->net_entries++;
return (DLADM_STATUS_OK);
}
/* Compare dates and return if t1 is equal, greater or lesser than t2 */
static int
{
return (NET_DATE_EQUAL);
}
return (NET_DATE_GREATER);
}
return (NET_DATE_LESSER);
}
/* Compare times and return if t1 is equal, greater or lesser than t2 */
static int
{
int cd;
if (cd == NET_DATE_GREATER) {
return (NET_TIME_GREATER);
} else if (cd == NET_DATE_LESSER) {
return (NET_TIME_LESSER);
} else {
return (NET_TIME_EQUAL);
}
return (NET_TIME_GREATER);
}
}
return (NET_TIME_LESSER);
}
/*
* Given a start and end time and start and end entries check if the
* times are within the range, and adjust, if needed.
*/
static dladm_status_t
{
if (compare_time(s, e) == NET_TIME_GREATER)
return (DLADM_STATUS_BADTIMEVAL);
}
if (s != NULL) {
}
}
if (e != NULL) {
}
}
return (DLADM_STATUS_OK);
}
/*
* Given a start and end time (strings), convert them into net_time_t
* and also check for the range given the head and tail of the list.
* If stime is lower then head or etime is greated than tail, adjust.
*/
static dladm_status_t
{
return (0);
}
return (0);
}
/*
* Walk the list from a given starting point and return when we find
* an entry that is greater or equal to st. lasttime will point to the
* previous time entry.
*/
static void
{
return;
}
return;
}
if (compare_time(st,
continue;
}
break;
}
}
/*
* Point entry (pe) functions
*/
/* Clear all the counters. Done after the contents are written to the file */
static void
{
int count;
}
*pentries = 0;
}
/* Update an entry in the point entry table */
static void
{
int count;
break;
}
return;
(*pentries)++;
}
/* Flush the contents of the point entry table to the file. */
static void
{
int count;
}
}
/*
* Net entry functions
*/
static net_entry_t *
{
int count;
return (ne);
}
return (NULL);
}
/* Get the entry for the descriptor, if it exists */
static net_desc_t *
{
int count;
ETHERADDRL) == 0 &&
ETHERADDRL) == 0 &&
&nd->net_desc_saddr) &&
&nd->net_desc_daddr)) {
return (nd1);
}
}
return (NULL);
}
/*
* Update the stat entries. The stats in the file are cumulative, so in order
* to have increments, we maintain a reference stat entry, which contains
* the stats when the record was first written and a total stat entry, which
* maintains the running count. When we want to add a stat entry, if it
* the reference stat entry, we don't come here. For subsequent entries,
* we get the increment by subtracting the current value from the reference
* stat and the total stat.
*/
static void
{
/* get the increment */
/* update total bytes */
}
/* Add the stat entry into the table */
static dladm_status_t
{
return (DLADM_STATUS_NOMEM);
/* Ptr to flow desc */
} else {
}
} else {
if (!ns->net_stat_isref) {
}
}
ne->net_entry_scount++;
return (DLADM_STATUS_OK);
}
static dladm_status_t
{
int count;
return (DLADM_STATUS_NOMEM);
return (DLADM_STATUS_NOMEM);
}
}
return (DLADM_STATUS_OK);
}
return (DLADM_STATUS_NOMEM);
}
return (DLADM_STATUS_OK);
}
/* Make an entry into the time sorted list */
static void
{
int count;
} else {
}
} else {
count = 0;
/* Just add it to the tail */
break;
}
0) {
} else {
}
return;
}
count++;
}
}
}
/* Add stat entry into the lists */
static dladm_status_t
{
int count;
return (DLADM_STATUS_NOMEM);
return (DLADM_STATUS_NOMEM);
}
return (DLADM_STATUS_NOMEM);
}
return (DLADM_STATUS_NOMEM);
}
}
return (DLADM_STATUS_NOMEM);
}
return (DLADM_STATUS_OK);
}
/* Free the entire table */
static void
{
}
}
net_table->net_time_entries = 0;
}
head->net_entry_scount = 0;
}
net_table->net_time_entries = 0;
}
/* Parse the exacct file, and return the parsed table. */
static void *
{
return (NULL);
}
return (NULL);
}
continue;
}
if (logtype == DLADM_LOGTYPE_FLOW) {
/* Flow Descriptor */
if ((scratch.eo_catalog &
/* Flow Stats */
} else if ((scratch.eo_catalog &
}
} else if (logtype == DLADM_LOGTYPE_LINK) {
/* Link Descriptor */
if ((scratch.eo_catalog &
/* Link Stats */
} else if ((scratch.eo_catalog &
}
} else {
EXD_DATA_MASK) == EXD_GROUP_NET_FLOW_DESC)) {
}
}
}
return ((void *)net_table);
}
/*
* Walk the ctime list. This is used when looking for usage records
* based on a "resource" name.
*/
{
/* Parse the log file */
return (status);
if (net_table->net_entries == 0)
return (DLADM_STATUS_OK);
/* Time range */
if (status != DLADM_STATUS_OK)
return (status);
/* Get to the resource we are interested in */
continue;
}
/* Find the first record */
if (!gotstart) {
&last_time);
break;
}
/* Write one entry and return if we are out of the range */
== NET_TIME_GREATER) {
if (tot_bytes != 0) {
}
return (DLADM_STATUS_OK);
}
/*
* If this is a reference entry, just print what we have
* and proceed.
*/
if (nns->net_stat_isref) {
if (tot_bytes != 0) {
tot_obytes, step);
}
continue;
}
if (--step == 0) {
tot_obytes, step);
} else {
}
}
if (tot_bytes != 0) {
}
return (status);
}
/*
* Walk the time sorted list if a resource is not specified.
*/
{
int count;
/* Parse the log file */
return (status);
if (net_table->net_entries == 0)
return (DLADM_STATUS_OK);
/* Find the first and last records and starting point */
if (status != DLADM_STATUS_OK)
return (status);
/*
* Could assert to be non-null, since get_time_range()
* would have adjusted.
*/
return (DLADM_STATUS_BADTIMEVAL);
/*
* Collect entries for all resources in a time slot before
* writing to the file.
*/
return (DLADM_STATUS_NOMEM);
}
/* Write header to file */
/* add_pe_to_file(fn, pe, ns, nentries, arg); */
/*
* We have crossed the time boundary, check if we need to
* print out now.
*/
/* return if we are out of the range */
if (pentries > 0) {
arg);
}
return (DLADM_STATUS_OK);
}
/* update the stats from the ns. */
if (--step == 0) {
if (pentries > 0) {
arg);
}
step = 1;
}
}
/*
* if this is a reference entry, just print what we have
* for this resource and proceed. We will end up writing
* the stats for all the entries when we hit a ref element,
* which means 'steps' for some might not be accurate, but
* that is fine, the alternative is to write only the
* resource for which we hit a reference entry.
*/
if (nns->net_stat_isref) {
if (pentries > 0) {
}
step = 1;
} else {
}
}
if (pentries > 0)
return (DLADM_STATUS_OK);
}
{
int count;
/* Parse the log file */
return (status);
if (net_table->net_entries == 0)
return (DLADM_STATUS_OK);
continue;
}
}
return (DLADM_STATUS_OK);
}
/*
* Walk the ctime list and display the dates of the records.
*/
{
/* Parse the log file */
return (status);
if (net_table->net_entries == 0)
return (DLADM_STATUS_OK);
/* get to the resource we are interested in */
continue;
}
}
/* get the starting point in the logfile */
if (!gotstart) {
&last_time);
break;
}
}
continue;
}
return (status);
}