/*
 * TCPVIEW
 *
 * Author:	Martin Hunt
 *		Networks and Distributed Computing
 *		Computing & Communications
 *		University of Washington
 *		Administration Building, AG-44
 *		Seattle, WA  98195
 *		Internet: martinh@cac.washington.edu
 *
 *
 * Copyright 1992 by the University of Washington
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appears in all copies and that both the
 * above copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the University of Washington not be
 * used in advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  This software is made
 * available "as is", and
 * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
 * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
 * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
 * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */
/*
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#ifndef lint
static char rcsid[] =
    "@(#) $Header: /usr/staff/martinh/tcpview/RCS/tv_etherent.c,v 1.1 1993/04/22 20:38:01 martinh Exp $ (UW)";
#endif

#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include "interface.h"

#include "etherent.h"

#ifdef __STDC__
static int next_sniffer(FILE *, struct etherent *);
#else
static int next_sniffer();
#endif

/* Hex digit to integer. */
static inline int
xdtoi(c)
{
	if (isdigit(c))
		return c - '0';
	else if (islower(c))
		return c - 'a' + 10;
	else
		return c - 'A' + 10;
}

static inline int
skip_space(f)
	FILE *f;
{
	int c;

	do {
		c = getc(f);
	} while (isspace(c) && c != '\n');

	return c;
}

static inline int
skip_line(f)
	FILE *f;
{
	int c;

	do
		c = getc(f);
	while (c != '\n' && c != EOF);

	return c;
}

struct etherent *next_etherent(fp)
FILE *fp;
{
  register int c, d, i;
  char *bp;
  static struct etherent e;
  static int nline = 1;
  int sniffer = 0;
  
  while(1) {
    c = skip_space(fp);
    if (c == '\n') continue;
    if (c == 's') sniffer++;
    break;
  }

  ungetc(c,fp);

  if (sniffer) {
    if (next_sniffer(fp,&e))
      return( &e );
    else
      return NULL;
  }
  
 top:
  while (nline) {
    /* Find addr */
    c = skip_space(fp);
    if (c == '\n')
      continue;
    /* If this is a comment, or first thing on line
       cannot be ethernet address, skip the line. */
    else if (c == 's') {
    } else
      if (!isxdigit(c))
	c = skip_line(fp);
      else {
	/* must be the start of an address */
	for (i = 0; i < 6; i += 1) {
	  d = xdtoi(c);
	  c = getc(fp);
	  if (c != ':') {
	    d <<= 4;
	    d |= xdtoi(c);
	    c = getc(fp);
	  }
	  e.addr[i] = d;
	  if (c != ':')
	    break;
	  c = getc(fp);
	}
	nline = 0;
      }
    if (c == EOF)
      return 0;
  }
  
  /* If we started a new line, 'c' holds the char past the ether addr,
     which we assume is white space.  If we are continuning a line,
     'c' is garbage.  In either case, we can throw it away. */
  
  c = skip_space(fp);
  if (c == '\n') {
    nline = 1;
    goto top;
  }
  else if (c == '#') {
    (void)skip_line(fp);
    nline = 1;
    goto top;
  }
  else if (c == EOF)
    return 0;
  
  /* Must be a name. */
  bp = e.name;
  /* Use 'd' to prevent buffer overflow. */
  d = sizeof(e.name) - 1;
  do {
    *bp++ = c;
    c = getc(fp);
  } while (!isspace(c) && c != EOF && --d > 0);
  *bp = '\0';
  if (c == '\n')
    nline = 1;
  
  return &e;
}


static int next_sniffer( fp, e )
     FILE *fp;
     struct etherent *e;
{
  char station[10],name[20],addrtype[20];
  u_char addr[20];
  int i;

  while(1) {
    if (fscanf(fp,"%s \"%[^\"]\" = addrtype\"%[IPDLC]\" %s",
	       station,name,addrtype,addr)==EOF)
      return 0;
    
/*    printf("%s %s %s\n",name,addrtype,addr); */
    if (!strcmp(addrtype,"DLC")) {
      for(i=0;i<12;i+=2)
	e->addr[i/2] = (xdtoi(addr[i]) << 4) + xdtoi(addr[i+1]);
      strncpy(e->name,name,20);
      return 1;
    }
  };
}

struct manufent *next_manufent(fp)
     FILE *fp;
{
  char name[10];
  u_char addr[8];
  int i;
  static struct manufent m;

  while( fscanf(fp,"%*s \"%[^\"]\" = %s%*[^\n]",name,addr)!=EOF) {
    if(*name) {
      if (name[0]!='\0') {
	i=0;
	do {
	  if( name[i] == (char)0 ) {
	    m.name[i] = (char)0;
	    break;
	  }
	  if( name[i] == ' ' )
	    m.name[i] = '_';
	  else
	    m.name[i] = name[i];
	} while(i++ < 6);
	m.name[6] = (char)0;
	for(i=0;i<6;i+=2)
	  m.addr[i/2] = (xdtoi(addr[i]) << 4) + xdtoi(addr[i+1]);
	return &m;
      }
    }
  }
  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1