runing a packet "trace" on tcp/ip?

runing a packet "trace" on tcp/ip?

Post by fkal.. » Fri, 01 Sep 1995 04:00:00



how do you run a trace on tcp/ip, udp, whatever packets arriving and
leaving in Linux, you know, showing source, destination, bytes, etc?

thanks

frank

 
 
 

runing a packet "trace" on tcp/ip?

Post by Joep Vesse » Fri, 01 Sep 1995 04:00:00



>how do you run a trace on tcp/ip, udp, whatever packets arriving and
>leaving in Linux, you know, showing source, destination, bytes, etc?

try tcpdump (e.g. on sunsite in system/Network/sunacm/Other/tcpdump)

joep.

 
 
 

runing a packet "trace" on tcp/ip?

Post by Kazimir Kylhe » Thu, 07 Sep 1995 04:00:00




>>how do you run a trace on tcp/ip, udp, whatever packets arriving and
>>leaving in Linux, you know, showing source, destination, bytes, etc?

>try tcpdump (e.g. on sunsite in system/Network/sunacm/Other/tcpdump)

>joep.

It's good you brought up the topic of Tcpdump. I recently fixed a bug
in the pcap library which prevents tcpdump under linux from correctly
operating with PPP interfaces. (I didn't bother fixing the SLIP, but
after I describe the bug, it should be obvious).

The problem is in pcap-linux.c.  The function which reads a snooped
packet from the desired interface realizes that the PPP driver
doesn't return a full packet, but one with four bytes removed from
the start. Hence it loads a PPP packet four bytes from the start of
the packet buffer (for SLIP, the offset is 16---even more info
is stripped).

The old code simply pads the beginning of the packet with four zeros.
This is incorrect, because the pcap compiler generates code which
checks the protocol field. For all internet protocols, bytes 2 and
3 should contain the 16-bit value 0x0021. Tcpdump works properly
when no matching expression is given, because no code (other
than a dummy ret #68) is generated. But as soon as you make
an expression, like "host <foo>" or "tcp" or "udp" it stops working
because the generated code looks for an 0x21 first to verify that
the packet is an inet packet.

A solution is to re-construct the 0x0021 value after the snoop packet
is retrieved from the PPP interface, rather than padding the 4-byte
with zeros. Unless you somehow have non-IP packets coming in through your PPP
interface, this should not be a problem.

I know that this may have been fixed by someone already, but I will
post "pcap-linux.c" anyway. All I did was add one line of code:

/*
 * Linux interface for packet capture lib

 * Based on the pcap-snoop.c file
 * May be freely redistributed as per the GNU license
 */
#include <sys/param.h>
#include <stdio.h>
#include <netdb.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <malloc.h>
#include <memory.h>
#include <unistd.h>

#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <net/bpf.h>

#include "pcap-int.h"

static char snoop_device[255];
struct ifreq ifr_orig;

void restore_interface()
{
  int fd;

  fd = socket(PF_INET, SOCK_PACKET, htons(0x0003));
  if (fd < 0) {
    printf("Warning: could not restore interface to normal.\n");
    return;
  }

  if (ioctl(fd, SIOCSIFFLAGS, &ifr_orig)<0)
    printf("Warning: could not restore interface to normal.\n");

Quote:}

int pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
  register int datalen;
  register int caplen;
  struct sockaddr from;
  int from_len;
  char *buf;
  int bufsize;

if (p->linktype == DLT_SLIP) {
    buf = (char *)p->buffer+16;
    bufsize = p->bufsize - 16;
    memset(p->buffer,0,16);  /* This should be fixed too -- Kaz      */
  } else if (p->linktype == DLT_PPP) {
    buf = (char *)p->buffer+4;
    bufsize = p->bufsize - 4;
    memset(p->buffer,0,4);

  } else {
    buf = (char *)p->buffer;
    bufsize = p->bufsize;
  }

  do {
    from_len = sizeof(from);
    datalen = recvfrom(p->fd,buf,bufsize,0,&from,&from_len);

    if (datalen < 0) {
      switch (errno) {
        case EWOULDBLOCK:
          return (0);
      }
      sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
      return (-1);
    }
  } while (strcmp(snoop_device,from.sa_data)); /* go until we find something
                                                 from the right interface */

  if (p->linktype == DLT_SLIP)
        datalen += 16;
  else if (p->linktype == DLT_PPP)
        datalen += 4;
  caplen = (datalen > p->bufsize) ? datalen : p->bufsize;

  if (caplen > p->snapshot)
    caplen = p->snapshot;

  if (p->fcode.bf_insns == NULL ||
      bpf_filter(p->fcode.bf_insns, (char *)p->buffer, datalen, caplen)) {
    struct pcap_pkthdr h;
    ++p->md.stat.ps_recv;

#ifdef SIOCGSTAMP
    if (ioctl(p->fd,SIOCGSTAMP,&h.ts)<0) /* ask for the timestamp */
#endif
      gettimeofday(&h.ts,0);

    h.len = datalen;
    h.caplen = caplen;
    (*callback)(user, &h, (char *)p->buffer);
    return (1);
  }
  return (0);

Quote:}

int pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
  ps->ps_drop = 0;
  ps->ps_recv = p->md.stat.ps_recv;
  ps->ps_ifdrop = 0;
  return (0);

Quote:}

pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
  pcap_t *p;
  struct ifreq ifr;

  p = (pcap_t *)malloc(sizeof(*p));
  if (p == NULL) {
    strcpy(ebuf, "no swap");
    return (0);
  }
  bzero(p, sizeof(*p));
  if (strncmp("et", device, 2) == 0)
    p->linktype = DLT_EN10MB;
  else if (strncmp("sl", device, 2) == 0)
    p->linktype = DLT_SLIP;
  else if (strncmp("pp", device, 2) == 0)
    p->linktype = DLT_PPP;
  else {
    sprintf(ebuf, "snoop: unknown physical layer type");
    goto bad;
  }
  p->fd = -1;
  p->bufsize = 4096;
  p->buffer = (u_char *)malloc(p->bufsize);
  if (p->buffer == NULL) {
    strcpy(ebuf, "no swap");
    goto bad;
  }
  p->fd = socket(PF_INET, SOCK_PACKET, htons(0x0003));
  if (p->fd < 0) {
    sprintf(ebuf, "snoop socket: %s", pcap_strerror(errno));
    goto bad;
  }

  if (p->linktype != DLT_SLIP && p->linktype != DLT_PPP && promisc) {
    strcpy(ifr.ifr_name, device);       /* interface we're gonna use */
    if (ioctl(p->fd, SIOCGIFFLAGS, &ifr) < 0 ) {    /* get flags */
      sprintf(ebuf, "socket ioctl get: %s", pcap_strerror(errno));
      goto bad;
    }
    ifr_orig = ifr;
    atexit(restore_interface);
    ifr.ifr_flags |= IFF_PROMISC;         /* set promiscuous mode */

    if (ioctl(p->fd, SIOCSIFFLAGS, &ifr) < 0 ) {    /* set flags */
      sprintf(ebuf, "socket ioctl set: %s", pcap_strerror(errno));
      goto bad;
    }
  }
  strcpy(snoop_device,device);

  p->snapshot = snaplen;
  return (p);
bad:
  if (p->fd >= 0)
          close(p->fd);
  if (p->buffer != NULL)
          free(p->buffer);
  free(p);
  return (0);

Quote:}

int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{

        p->fcode = *fp;
        return (0);

Quote:}

--

one of the public key servers -- the key id is 0xD3C7995D.
Microsoft users: crash test dummies?
 
 
 

1. "Novell-like","non-TCP/IP","networking" OS to place Unix

Perhaps a somewhat ill-defined question, but:  Is there an OS for
Unix machines (Sun, HP, etc.) which is network oriented, like
Novell, and not dependent on TCP/IP?


Jerry Hamilton             -<*>-         non-work PGP Public Key
McDonnell Douglas            |           94 5D 0B 2A 24 9D 1C 6F  
Orange County, CA                        86 E1 00 4C A7 12 6C 74
--

2. adding ethernet card

3. GETSERVBYNAME()????????????????????"""""""""""""

4. XFree86 3.3 Setup Problem

5. netstat -s output: "packets pruned" and "packets collapsed"

6. Mosaic w/X version 2.xx

7. ??: TCP/IP High "colls" and "errs" Counts???

8. Bind Help

9. """"""""My SoundBlast 16 pnp isn't up yet""""""""""""

10. ppp server "ip-up" "ip-down" problem

11. Tracing TCP/IP packets from NIC to TCP

12. Type "(", ")" and "{", "}" in X...

13. Could funky pppd MTU cause "unclean" and "NEW" packets?