open()
dlattachreq()
dlokack()
dlpromisconreq()
dlokack()
dlbindreq()
dlokack()
strioctl()
ioctl(,I_FLUSH,FLUSHR)
getmsg()
print_pkt()

    1  /*********************************************
    2   * sniff.c
    3   *
    4   * packet monitor using DLPI
    5   *
    6   * gcc sniff.c -lnsl -o sniff
    7   *
    8   ********************************************/
    9  #Include <netinet/in.h>
   10  #include <sys/types.h>
   11  #include <sys/socket.h>
   12  #include <sys/stropts.h>
   13  #include <sys/dlpi.h>
   14  #include <fcntl.h>
   15  #include <stdio.h>
   16  #include <sys/signal.h>
   17  #include <sys/stream.h>
   18  #include <string.h>
   19  #include <net/if.h>
   20  #include <netinet/if_ether.h>
   21  #include <netinet/in_systm.h>
   22  #include <netinet/tcp.h>
   23  #include <netinet/ip.h>
   24  #include <sys/varargs.h>
   25  #include <errno.h>
   26  #include <unistd.h>
   27
   28  #define  ERR_MSG_MAX 300
   29  #define  MAXDLBUFSIZE  8192
   30  #define  DLBUFSIZE     8192
   31  #define  TCP_DATA_PRINT_LENGTH  100
   32  #define  PRINT_MAC_ADDR(ether_addr_octet)     {         \
   33          int i;                                          \
   34          for ( i =0; i < 6; i++){                        \
   35              printf("%02x",(ether_addr_octet[i]));       \
   36              if(i != 5)                                  \
   37                  printf(":");                            \
   38          }                                               \
   39      }
   40
   41  void   print_packet(caddr_t,  int);
   42  void   print_usage(char *);
   43  int    dlattachreq(int, t_uscalar_t, caddr_t );
   44  int    dlpromisconreq(int, t_uscalar_t, caddr_t);
   45  int    dlbindreq(int, t_uscalar_t, t_uscalar_t, uint16_t, uint16_t, t_uscalar_t, caddr_t);
   46  void   print_err(int , char *, ...);
   47  int    dldetachreq(int , caddr_t);
   48  int    dlpromiscoffreq(int, t_uscalar_t, caddr_t);
   49
   50  int
   51  main(int argc, char *argv[])
   52  {


   55      union  DL_primitives  *dlp;
   56      int                    flags = 0;








   65
   66      if (argc != 2)
   67          print_usage(argv[0]);
   68
   69      interface = argv[1];
   70      if ((instance = strpbrk(interface, "0123456789")) == NULL){
   71          fprintf(stderr, "%s: no instance specified\n", interface);
   72          print_usage(argv[0]);
   73      }
   74
   75      ppa = atoi(instance);
   76
   77      strncpy(devname, interface, instance - interface);
   78
   79      sprintf(devpath, "/dev/%s",devname);
   80
   81      /*

   83       */
   84      if((fd = open (devpath , O_RDWR)) < 0 ){
   85          perror("open");
   86          exit(1);
   87      }
   88
   89      /*

   91       */
   92      if(dlattachreq(fd, ppa, buf) < 0){
   93          fprintf(stderr, "%s: no such instance\n", interface);
   94          print_usage(argv[0]);
   95      }
   96
   97      /*

   99       */
  100      if(dlpromisconreq(fd, DL_PROMISC_PHYS, buf) < 0){
  101          fprintf(stderr, "%s: Cannot set promiscuous mode\n", interface);
  102          exit(1);
  103      }
  104
  105      /*

  107       */
  108      if(dlbindreq (fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0, buf) < 0){
  109          fprintf(stderr, "%s: Cannot bind to ETHERTYPE_IP\n", interface);
  110          exit(1);
  111      }
  112
  113      /*

  115       */
  116      strioc.ic_cmd    = DLIOCRAW;
  117      strioc.ic_timout = -1;
  118      strioc.ic_len    = 0;
  119      strioc.ic_dp     = NULL;
  120      if(ioctl(fd, I_STR, &strioc) < 0){
  121          perror("ioctl: I_STR: DLIOCRAW");
  122          exit(1);
  123      }
  124
  125      /*

  127       */
  128      if (ioctl(fd, I_FLUSH, FLUSHR) < 0){
  129          perror("ioctl: I_FLUSH");
  130          exit(1);
  131      }
  132
  133      databuf.maxlen = MAXDLBUFSIZE;
  134      databuf.len = 0;
  135      databuf.buf = (caddr_t)buf;
  136
  137      while (getmsg(fd, NULL, &databuf, &flags) == 0) {
  138          if (databuf.len > 0)
  139              print_packet(databuf.buf, databuf.len);
  140      }
  141
  142      perror("getmsg");
  143      exit(1);
  144  }
  145
  146  void
  147  print_packet(caddr_t buf, int len)
  148  {
  149      struct ether_header   *ether;
  150      struct tcphdr         *tcp;
  151      struct ip             *ip;
  152      u_char                *tcpdata;
  153      int                    etherlen;
  154      int                    iphlen;
  155      int                    iptotlen;
  156      int                    tcphlen;
  157      int                    tcpdatalen;
  158
  159      etherlen = sizeof(struct ether_header);
  160      ether = (struct ether_header *)buf;
  161
  162      /*

  164       */
  165      if(ether->ether_type != ETHERTYPE_IP)
  166          return;
  167
  168      /*



  172       */
  173      if(len < etherlen + sizeof(struct ip) + sizeof(struct tcphdr) )
  174          return;
  175
  176      /*


  179       */
  180      ip = (struct ip *)malloc(len);
  181      memcpy(ip, buf + etherlen, len);
  182
  183      /*

  185       */
  186      if(ip->ip_p != IPPROTO_TCP)
  187          goto error;
  188
  189      iphlen = ip->ip_hl << 2;
  190
  191      /*



  195       */
  196      if(len < etherlen + iphlen + sizeof(struct tcphdr) )
  197          goto error;
  198
  199      tcp = (struct tcphdr *)((u_char *)ip + iphlen);
  200      tcphlen = tcp->th_off << 2;
  201
  202      /*



  206       */
  207      if(len < etherlen + iphlen + tcphlen )
  208          goto error;
  209
  210      printf("\n----Ether Header----\n");
  211      printf("src addr    : ");
  212      PRINT_MAC_ADDR(ether->ether_shost.ether_addr_octet);
  213      printf("\n");
  214      printf("dest addr   : ");
  215      PRINT_MAC_ADDR(ether->ether_dhost.ether_addr_octet);
  216      printf("\n");
  217      printf("ether type  : 0x%x\n",ether->ether_type);
  218
  219      printf("----IP Header----\n");
  220      printf("version     : %d\n",ip->ip_v);
  221      printf("header len  : %d (%d bytes)\n",ip->ip_hl, ip->ip_hl <<2);
  222      printf("tos         : %d\n",ip->ip_tos);
  223      printf("total len   : %d\n",ntohs(ip->ip_len));
  224      printf("id          : %d\n",ntohs(ip->ip_id));
  225      printf("frag offset : %d\n",ip->ip_off);
  226      printf("ttl         : %d\n",ip->ip_ttl);
  227      printf("protocol    : %d\n",ip->ip_p);
  228      printf("checksum    : 0x%x\n",ip->ip_sum);
  229      printf("src address : %s\n",inet_ntoa(ip->ip_src));
  230      printf("dst address : %s\n",inet_ntoa(ip->ip_dst));
  231
  232      printf("----TCP Header----\n");
  233      printf("source port : %d\n",ntohs(tcp->th_sport));
  234      printf("dest port   : %d\n",ntohs(tcp->th_dport));
  235      printf("seq         : %u\n",ntohl(tcp->th_seq));
  236      printf("ack         : %u\n",ntohl(tcp->th_ack));
  237      printf("data offset : %d (%d bytes)\n",tcp->th_off, tcp->th_off <<2);
  238      printf("flags       : ");
  239      if((tcp->th_flags | TH_FIN) == tcp->th_flags)
  240          printf("FIN ");
  241      if((tcp->th_flags | TH_SYN) == tcp->th_flags)
  242          printf("SIN ");
  243      if((tcp->th_flags | TH_RST) == tcp->th_flags)
  244          printf("RST ");
  245      if((tcp->th_flags | TH_PUSH) == tcp->th_flags)
  246          printf("PUSH ");
  247      if((tcp->th_flags | TH_ACK) == tcp->th_flags)
  248          printf("ACK ");
  249      if((tcp->th_flags | TH_URG) == tcp->th_flags)
  250          printf("URG ");
  251      printf("\n");
  252      printf("window      : %d\n",ntohs(tcp->th_win));
  253      printf("check sum   : 0x%x\n",tcp->th_sum);
  254      printf("urt_ptr     : %d\n",tcp->th_urp);
  255
  256      /*



  260       */
  261      iptotlen   = ntohs(ip->ip_len);
  262      tcpdatalen = iptotlen - iphlen - tcphlen;
  263      if( tcpdatalen > len - etherlen - iphlen - tcphlen)
  264          tcpdatalen = len - etherlen - iphlen - tcphlen;
  265
  266      if( tcpdatalen > 0){
  267          int   i = 0;
  268
  269          tcpdata = (u_char *)tcp + tcphlen;
  270          printf("------DATA-------\n");
  271          printf("data length : %d\n", tcpdatalen);
  272          /*

  274           */
  275          while ( i < tcpdatalen && i < TCP_DATA_PRINT_LENGTH){
  276              if(isprint(tcpdata[i]))
  277                  printf("%c",tcpdata[i]);
  278              i++;
  279          }
  280      }
  281
  282      printf("\n\n");
  283
  284    error:
  285      free(ip);
  286      return;
  287  }
  288
  289  /*****************************************************************************
  290   * print_usage()
  291   *

  293   *****************************************************************************/
  294  void
  295  print_usage(char *argv)
  296  {
  297      printf("Usage: %s ifname \n",argv);
  298      printf("  Example) %s eri0\n", argv);
  299      exit(1);
  300  }
  301
  302  /*****************************************************************************
  303   * dlattachreq()
  304   *

  306   *
  307   *****************************************************************************/
  308  int
  309  dlattachreq(int fd, t_uscalar_t ppa ,caddr_t buf)
  310  {
  311      union DL_primitives  *primitive;
  312      dl_attach_req_t       attachreq;
  313      struct strbuf         ctlbuf;
  314      int                   flags = 0;
  315      int                   ret;
  316
  317      attachreq.dl_primitive = DL_ATTACH_REQ;
  318      attachreq.dl_ppa = ppa;
  319
  320      ctlbuf.maxlen = 0;
  321      ctlbuf.len    = sizeof(attachreq);
  322      ctlbuf.buf    = (caddr_t)&attachreq;
  323
  324      if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){
  325          fprintf(stderr, "dlattachreq: putmsg: %s", strerror(errno));
  326          return(-1);
  327      }
  328
  329      ctlbuf.maxlen = MAXDLBUFSIZE;
  330      ctlbuf.len = 0;
  331      ctlbuf.buf = (caddr_t)buf;
  332
  333      if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) {
  334          fprintf(stderr, "dlattachreq: getmsg: %s\n", strerror(errno));
  335          return(-1);
  336      }
  337
  338      primitive = (union DL_primitives *) ctlbuf.buf;
  339      if ( primitive->dl_primitive != DL_OK_ACK){
  340          fprintf(stderr, "dlattachreq: not DL_OK_ACK\n");
  341          return(-1);
  342      }
  343
  344      return(0);
  345  }
  346
  347  /*****************************************************************************
  348   * dlpromisconreq()
  349   *

  351   *
  352   *****************************************************************************/
  353  int
  354  dlpromisconreq(int fd, t_uscalar_t level, caddr_t buf)
  355  {
  356      union DL_primitives  *primitive;
  357      dl_promiscon_req_t    promisconreq;
  358      struct strbuf         ctlbuf;
  359      int                   flags = 0;
  360      int                   ret;
  361
  362      promisconreq.dl_primitive = DL_PROMISCON_REQ;
  363      promisconreq.dl_level = level;
  364
  365      ctlbuf.maxlen = 0;
  366      ctlbuf.len    = sizeof (promisconreq);
  367      ctlbuf.buf    = (caddr_t)&promisconreq;
  368
  369      if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){
  370          fprintf(stderr, "dlpromisconreq: putmsg: %s", strerror(errno));
  371          return(-1);
  372      }
  373
  374      ctlbuf.maxlen = MAXDLBUFSIZE;
  375      ctlbuf.len = 0;
  376      ctlbuf.buf = (caddr_t)buf;
  377
  378      if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) {
  379          fprintf(stderr, "dlpromisconreq: getmsg: %s\n", strerror(errno));
  380          return(-1);
  381      }
  382
  383      primitive = (union DL_primitives *) ctlbuf.buf;
  384      if ( primitive->dl_primitive != DL_OK_ACK){
  385          fprintf(stderr, "dlpromisconreq: not DL_OK_ACK\n");
  386          return(-1);
  387      }
  388
  389      return(0);
  390  }
  391
  392  /*****************************************************************************
  393   * dlbindreq()
  394   *

  396   *
  397   *****************************************************************************/
  398  int
  399  dlbindreq(
  400      int fd,
  401      t_uscalar_t sap,
  402      t_uscalar_t max_conind,
  403      uint16_t    service_mode,
  404      uint16_t    conn_mgmt,
  405      t_uscalar_t xidtest_flg,
  406      caddr_t     buf
  407      )
  408  {
  409      union DL_primitives  *primitive;
  410      dl_bind_req_t         bindreq;
  411      struct strbuf         ctlbuf;
  412      int                   flags = 0;
  413      int                   ret;
  414
  415      bindreq.dl_primitive    = DL_BIND_REQ;
  416      bindreq.dl_sap          = sap;
  417      bindreq.dl_max_conind   = max_conind;
  418      bindreq.dl_service_mode = service_mode;
  419      bindreq.dl_conn_mgmt    = conn_mgmt;
  420      bindreq.dl_xidtest_flg  = xidtest_flg;
  421
  422      ctlbuf.maxlen = 0;
  423      ctlbuf.len    = sizeof(bindreq);
  424      ctlbuf.buf    = (caddr_t)&bindreq;
  425
  426      if (putmsg(fd, &ctlbuf, (struct strbuf*) NULL, flags) < 0){
  427          fprintf(stderr, "dlbindreq: putmsg: %s", strerror(errno));
  428          return(-1);
  429      }
  430
  431      ctlbuf.maxlen = MAXDLBUFSIZE;
  432      ctlbuf.len    = 0;
  433      ctlbuf.buf    = (caddr_t)buf;
  434
  435      if ((ret = getmsg(fd, &ctlbuf, (struct strbuf *)NULL, &flags)) < 0) {
  436          fprintf(stderr, "dlbindreq: getmsg: %s\n", strerror(errno));
  437          return(-1);
  438      }
  439
  440      primitive = (union DL_primitives *) ctlbuf.buf;
  441

sniff.c


FastEthernet


# ./sniff /dev/hme 0			     
					     
----Ether Header----			     
src addr    : 8:0:20:91:a6:90:		     
dest addr   : 0:0:f4:5d:6a:a9:		     
ether type  : 800			     
----IP Header----			     
version     : 4				     
ihl         : 5				     
tos         : 0				     
tot length  : 40			     
id          : 59439			     
frag_off    : 16384			     
ttl         : 64			     
protocol    : 6				     
check       : 26633			     
saddr       : 172.29.73.90		     
daddr       : 172.29.73.2		     
----TCP Header----			     
source port : 1021			     
dest port   : 2049			     
sequence    : 1137017927		     
ack seq     : 1486710309		     
data offset : 5				     
flags       : ACK			     
window      : 50400			     
check       : 28047			     
urt_ptr     : 0				     
------DATA-------                            




stream.gif



   32          union   DL_primitives *dlp;



M_DATA
M_PROTO
M_PCPROTO
   48          if((fd = open (device , O_RDWR)) < 0 )
   51          dlattachreq(fd, ppa);
   85          attach_req.dl_primitive = DL_ATTACH_REQ;


typedef struct {
       t_uscalar_t     dl_primitive;           /* set to DL_ATTACH_REQ */
       t_uscalar_t     dl_ppa;                 /* id of the PPA */
} dl_attach_req_t;
struct strbuf {
       int     maxlen;         /* no. of bytes in buffer */
       int     len;            /* no. of bytes returned */
       caddr_t buf;            /* pointer to data */
};
DL_ATTACH_REQ
ppa
   94          if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
putmsg()
#include <stropts.h>
int putmsg(int fildes, const struct strbuf *ctlptr, const struct strbuf *da taptr, int flags);


dlpi_sequence.gif


  201  strgetmsg(fd, ctlp, datap, flagsp, caller)
getmsg()
#include <stropts.h>
int getmsg(int fildes, struct strbuf *ctlptr, struct strbuf *dataptr, int * flagsp);


  217          if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
  218                  (void) sprintf(errmsg, "%s:  getmsg", caller);
  219                  syserr(errmsg);
  220          }


  164          strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack");
  165
  166          dlp = (union DL_primitives *) ctl.buf;
  167
  168          expecting(DL_OK_ACK, dlp);
   54          dlpromisconreq(fd, DL_PROMISC_PHYS);
   55          dlokack(fd, buf);
   56
   57          dlbindreq (fd, FLAMETYPE, 0, DL_CLDLS, 0, 0);
   58          dlbindack (fd, buf);
dlpromisconreq
dlbindreq
   60          if (strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0)
   61                  syserr("DLIOCRAW");
ioctl()
#include <unistd.h>
#include <stropts.h>
#include <sys/conf.h>
int ioctl(int fildes, int command, /* arg */ ...);


  285          rc = ioctl(fd, I_STR, &sioc);
struct strioctl {




}; 


   63          if (ioctl(fd, I_FLUSH, FLUSHR) < 0)
      #define FLUSHR 0x01 /* flush read queue */

   66          data.buf = (char *) databuf;
   67          data.maxlen = MAXDLBUF;
   68          data.len = 0;
   69
   70          while (getmsg(fd, NULL, &data, &flags) == 0) {









man page
docs.sun.com

   54          dlpromisconreq(fd, DL_PROMISC_SAP); 
/*
 * DLPI promiscuous mode definitions
 */
#define DL_PROMISC_PHYS         0x01    /* promiscuous mode at phys level */
#define DL_PROMISC_SAP          0x02    /* promiscous mode at sap level */
#define DL_PROMISC_MULTI        0x03    /* promiscuous mode for multicast */




トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS