Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
     5         kx /*
     5         kx  * Show ICMP packets incoming (and detect bombs)
     5         kx  *   modified from ping
     5         kx  *   1994/1995 - Laurent Demailly - <dl@hplyot.obspm.fr>
     5         kx  */
     5         kx 
     5         kx /* note : the original bsd code was *very* buggy !!!
     5         kx           it should be ok, now */
     5         kx 
     5         kx /*
     5         kx  * Print out the packet, if it came from us.  This logic is necessary
     5         kx  * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
     5         kx  * which arrive ('tis only fair).  This permits multiple copies of this
     5         kx  * program to be run without having intermingled output (or statistics!).
     5         kx  */
     5         kx 
     5         kx #include <string.h>
     5         kx #include <stddef.h> /* offsetof */
     5         kx #include	"defs.h"
     5         kx 
     5         kx #ifndef ANSI_OFFSETOF
     5         kx #ifndef offsetof
     5         kx #        define offsetof(t,m)  (int)((&((t *)0L)->m))
     5         kx #endif
     5         kx #endif
     5         kx 
     5         kx char to_hex(a)
     5         kx   int a;
     5         kx {
     5         kx   return ((char)(a <= 9 ? a + '0' : (a -10) + 'A'));
     5         kx }
     5         kx 
     5         kx int pr_pack(buf, cc, from)
     5         kx char			*buf;	/* ptr to start of IP header */
     5         kx int			cc;	/* total size of received packet */
     5         kx struct sockaddr_in	*from;	/* address of sender */
     5         kx {
     5         kx   int			iphdrlen,doipdecoding=1;
     5         kx   struct ip		*ip;	/* ptr to IP header */
     5         kx   register struct icmp	*icp;	/* ptr to ICMP header */
     5         kx   struct tcphdr 	*tp;    /* ptr to TCP header */
     5         kx   time_t			t;
     5         kx   char			*pr_type(),*pr_subtype(),*strtime;
     5         kx   struct hostent	*hostent=NULL;
     5         kx   struct servent	*servent=NULL;
     5         kx   static char prbuf[1024];	/* provide enough room for even the longest hosts*/
     5         kx 	
     5         kx   /*
     5         kx    * We have to look at the IP header, to get its length.
     5         kx    * We also verify that what follows the IP header contains at
     5         kx    * least an ICMP header (8 bytes minimum).
     5         kx    */
     5         kx   ip = (struct ip *) buf;
     5         kx   iphdrlen = ip->ip_hl << 2;	/* convert # 16-bit words to #bytes */
     5         kx   if (cc < iphdrlen + ICMP_MINLEN) {
     5         kx     sprintf(prbuf,"packet too short (%d bytes) from %s", cc,
     5         kx 	    inet_ntoa(from->sin_addr));
     5         kx     if (syslogdoutput) {
     5         kx       syslog(LOG_WARNING,"%s",prbuf);
     5         kx       } else {
     5         kx 	puts(prbuf);
     5         kx 	fflush(stdout);
     5         kx       }
     5         kx     return -1;
     5         kx   }
     5         kx   cc -= iphdrlen;
     5         kx 
     5         kx   icp = (struct icmp *)(buf + iphdrlen);
     5         kx   switch (icp->icmp_type) 
     5         kx     {
     5         kx     case ICMP_ECHO :
     5         kx     case ICMP_ECHOREPLY :
     5         kx       doipdecoding=0;
     5         kx       if (verbose<2) break;
     5         kx     case ICMP_SOURCEQUENCH :
     5         kx     case ICMP_TIMXCEED : 
     5         kx     case ICMP_REDIRECT :
     5         kx       if (!verbose) break;
     5         kx     default :
     5         kx       if (!nonamequery) {
     5         kx 	hostent=gethostbyaddr((char*)&(from->sin_addr.s_addr),
     5         kx 			      sizeof (struct in_addr),
     5         kx 			      AF_INET);
     5         kx       }
     5         kx       if (!syslogdoutput) {
     5         kx 	t=time((time_t *)NULL); strtime=(char *)ctime(&t);
     5         kx 	strtime+=4;		/* skip day name */
     5         kx 	strtime[15]=0;		/* keep MMM DD HH:MM:SS */
     5         kx         printf("%s ",strtime);
     5         kx       }
     5         kx       sprintf(prbuf,hostent?"ICMP_%s%s < %s [%s]":"ICMP_%s%s < %s",
     5         kx 	      pr_type(icp->icmp_type),
     5         kx 	      icp->icmp_type==ICMP_UNREACH?pr_subtype(icp->icmp_code):"",
     5         kx 	      inet_ntoa(from->sin_addr),
     5         kx 	      hostent?hostent->h_name:NULL
     5         kx 	      );
     5         kx       if ( doipdecoding && 
     5         kx            ( cc >= offsetof(struct icmp,icmp_ip.ip_src)+sizeof(icp->icmp_ip.ip_dst) ) )
     5         kx 	{
     5         kx 	  if (showsrcip) 
     5         kx 	    { /*  icp->icmp_ip.ip_src.s_addr == local host, show it
     5         kx 		  only if requested (might be usefull for host with several
     5         kx 		  interfaces */
     5         kx 	      if (!nonamequery) {
     5         kx 		hostent=gethostbyaddr((char*)&(icp->icmp_ip.ip_src.s_addr),
     5         kx 				      sizeof (struct in_addr),
     5         kx 				      AF_INET);
     5         kx 	      }
     5         kx 	      sprintf(prbuf+strlen(prbuf),hostent?" - %s [%s]":" - %s",
     5         kx 		      inet_ntoa(icp->icmp_ip.ip_src),
     5         kx 		      hostent?hostent->h_name:NULL);
     5         kx 	    }
     5         kx 	  if (cc>=offsetof(struct icmp,icmp_ip.ip_dst)+sizeof(icp->icmp_ip.ip_dst))
     5         kx 	    {
     5         kx 	      if (!nonamequery) {
     5         kx 		hostent=gethostbyaddr((char*)&(icp->icmp_ip.ip_dst.s_addr),
     5         kx 				      sizeof (struct in_addr),
     5         kx 				      AF_INET);
     5         kx 	      }
     5         kx 	      sprintf(prbuf+strlen(prbuf),hostent?" > %s [%s]":" > %s",
     5         kx 		      inet_ntoa(icp->icmp_ip.ip_dst),
     5         kx 		      hostent?hostent->h_name:NULL);
     5         kx 	      tp = (struct tcphdr *)((char *)&(icp->icmp_dun)+sizeof(struct ip)) ;
     5         kx #if defined(__GLIBC__) && (__GLIBC__ >= 2)
     5         kx 	      if (cc>=offsetof(struct icmp,icmp_dun)+sizeof(struct ip)+offsetof(struct tcphdr,seq)+sizeof(tp->seq))
     5         kx 		{
     5         kx 		  if (noportquery) {
     5         kx 		      sprintf(prbuf+strlen(prbuf)," sp=%d dp=%d seq=0x%8.8x",
     5         kx 			  ntohs(tp->source),ntohs(tp->dest),
     5         kx                           ntohl(tp->seq));
     5         kx 		  } else {
     5         kx 		    if ((servent=getservbyport(ntohs(tp->source),NULL))) 
     5         kx 		      sprintf(prbuf+strlen(prbuf)," sp=%d [%s]",
     5         kx 			      ntohs(tp->source),servent->s_name);
     5         kx 		    else
     5         kx 		      sprintf(prbuf+strlen(prbuf)," sp=%d",tp->source);
     5         kx 		    if ((servent=getservbyport(ntohs(tp->dest),NULL))) 
     5         kx 		      sprintf(prbuf+strlen(prbuf)," dp=%d [%s] seq=0x%8.8x",
     5         kx 			      ntohs(tp->dest),servent->s_name,
     5         kx 			      ntohl(tp->seq));
     5         kx 		    else
     5         kx 		      sprintf(prbuf+strlen(prbuf)," dp=%d seq=0x%8.8x",
     5         kx 			      ntohs(tp->dest),ntohl(tp->seq));
     5         kx 		  }
     5         kx 		}
     5         kx #else
     5         kx 	      if (cc>=offsetof(struct icmp,icmp_dun)+sizeof(struct ip)+offsetof(struct tcphdr,th_seq)+sizeof(tp->th_seq))
     5         kx 		{
     5         kx 		  if (noportquery) {
     5         kx 		      sprintf(prbuf+strlen(prbuf)," sp=%d dp=%d seq=0x%8.8x",
     5         kx 			  ntohs(tp->th_sport),ntohs(tp->th_dport),
     5         kx                           ntohl(tp->th_seq));
     5         kx 		  } else {
     5         kx 		    if ((servent=getservbyport(ntohs(tp->th_sport),NULL))) 
     5         kx 		      sprintf(prbuf+strlen(prbuf)," sp=%d [%s]",
     5         kx 			      ntohs(tp->th_sport),servent->s_name);
     5         kx 		    else
     5         kx 		      sprintf(prbuf+strlen(prbuf)," sp=%d",tp->th_sport);
     5         kx 		    if ((servent=getservbyport(ntohs(tp->th_dport),NULL))) 
     5         kx 		      sprintf(prbuf+strlen(prbuf)," dp=%d [%s] seq=0x%8.8x",
     5         kx 			      ntohs(tp->th_dport),servent->s_name,
     5         kx 			      ntohl(tp->th_seq));
     5         kx 		    else
     5         kx 		      sprintf(prbuf+strlen(prbuf)," dp=%d seq=0x%8.8x",
     5         kx 			      ntohs(tp->th_dport),ntohl(tp->th_seq));
     5         kx 		  }
     5         kx 		}
     5         kx #endif
     5         kx 	    }
     5         kx 	}
     5         kx       sprintf(prbuf+strlen(prbuf)," sz=%d(+%d)",cc,iphdrlen);
     5         kx       if (syslogdoutput) {
     5         kx 	  syslog(LOG_NOTICE,"%s",prbuf);
     5         kx 	} else {
     5         kx 	  puts(prbuf);
     5         kx 	  fflush(stdout);
     5         kx 	  if (verbose>2) {	/* hexa dump adapted from a file dump by dl (me!) */
     5         kx 	    /* certainly not the smartest around, but it works !*/
     5         kx 	    static char	h[] = "                                          ";
     5         kx 	    static char	a[] = "                ";
     5         kx 	    int	i,j,b,n, flagNEof;
     5         kx 	    unsigned char	*pbuf=(unsigned char *)buf;
     5         kx 	
     5         kx 	    n = 0;
     5         kx 	    flagNEof = 1;
     5         kx 	    while (flagNEof) {
     5         kx 	      i = j = 0;
     5         kx 	      while (i < 16 && (flagNEof = cc--)) {
     5         kx 		b= (int)(*(pbuf++));
     5         kx 		h[j++] = to_hex(b >> 4);
     5         kx 		h[j++] = to_hex(b & 0x0F);
     5         kx 		j += i % 2 + ((i == 7) << 1);
     5         kx 		a[i++] = (b > 31 && b < 127) ? b : '.';
     5         kx 	      }
     5         kx 	      if (i==0) break;
     5         kx 	      while (i < 16) {
     5         kx 		h[j++] = ' ';
     5         kx 		h[j++] = ' ';
     5         kx 		j += i % 2 + ((i == 7) << 1);
     5         kx 		a[i++] = ' ';
     5         kx 	      }
     5         kx 	      printf("%04X :  %s   %s\n", n, h, a);
     5         kx 	      n += 16;
     5         kx 	    }
     5         kx 	  }
     5         kx 	}
     5         kx     }
     5         kx   return 0;
     5         kx }
     5         kx 
     5         kx /*
     5         kx  * Convert an ICMP "type" field to a printable string.
     5         kx  * This is called for ICMP packets that are received that are not
     5         kx  * ICMP_ECHOREPLY packets.
     5         kx  */
     5         kx 
     5         kx char *
     5         kx pr_type(t)
     5         kx register int t;
     5         kx {
     5         kx 	static char	*ttab[] = {
     5         kx 		"Echo_Reply",
     5         kx 		"1",
     5         kx 		"2",
     5         kx 		"Dest_Unreachable",
     5         kx 		"Source_Quench",
     5         kx 		"Redirect",
     5         kx 		"6",
     5         kx 		"7",
     5         kx 		"Echo",
     5         kx 		"RouterAdvert",
     5         kx 		"Router_Solicit",
     5         kx 		"Time_Exceeded",
     5         kx 		"Parameter_Problem",
     5         kx 		"Timestamp",
     5         kx 		"Timestamp_Reply",
     5         kx 		"Info_Request",
     5         kx 		"Info_Reply",
     5         kx 		"Mask_Request",
     5         kx 		"Mask_Reply"
     5         kx 	};
     5         kx 
     5         kx 	if (t < 0 || t > 18) {
     5         kx 	  static char buf[80];
     5         kx 	  sprintf(buf,"OUT_OF_RANGE(%d)",t);
     5         kx 	  return(buf);
     5         kx 	}
     5         kx 	return(ttab[t]);
     5         kx }
     5         kx 
     5         kx /*
     5         kx  * Convert an ICMP UNREACH sub-"type" field to a printable string.
     5         kx  */
     5         kx 
     5         kx char *
     5         kx pr_subtype(t)
     5         kx register int t;
     5         kx {
     5         kx 	static char	*ttab[] = {
     5         kx 	  "Net",
     5         kx 	  "Host",
     5         kx 	  "Protocol",
     5         kx 	  "Port",
     5         kx 	  "Frag",
     5         kx 	  "Source",
     5         kx 	  "DestNet",
     5         kx 	  "DestHost",
     5         kx 	  "Isolated",
     5         kx 	  "AuthNet",
     5         kx 	  "AuthHost",
     5         kx 	  "NetSvc",
     5         kx 	  "HostSvc",
     5         kx 	  "Filtered",
     5         kx 	  "PrecdViolation",
     5         kx 	  "PrecdCut"
     5         kx 	  };
     5         kx 	static char buf[80];
     5         kx 	
     5         kx 	if (t < 0 || t > 15) {
     5         kx 	  sprintf(buf,"[OUT_OF_RANGE(%d)]",t);
     5         kx 	} else {
     5         kx 	  sprintf(buf,"[%s]",ttab[t]);
     5         kx         }
     5         kx 	return(buf);
     5         kx }
     5         kx