home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / network / src_1218.zip / ICMPHDR.C < prev    next >
C/C++ Source or Header  |  1991-01-27  |  2KB  |  103 lines

  1. /* ICMP header conversion routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "internet.h"
  7. #include "ip.h"
  8. #include "icmp.h"
  9.  
  10. /* Generate ICMP header in network byte order, link data, compute checksum */
  11. struct mbuf *
  12. htonicmp(icmp,data)
  13. struct icmp *icmp;
  14. struct mbuf *data;
  15. {
  16.     struct mbuf *bp;
  17.     register char *cp;
  18.     int16 checksum;
  19.  
  20.     if((bp = pushdown(data,ICMPLEN)) == NULLBUF)
  21.         return NULLBUF;
  22.     cp = bp->data;
  23.  
  24.     *cp++ = icmp->type;
  25.     *cp++ = icmp->code;
  26.     cp = put16(cp,0);        /* Clear checksum */
  27.     switch(icmp->type){
  28.     case ICMP_DEST_UNREACH:
  29.         if(icmp->code == ICMP_FRAG_NEEDED){
  30.             /* Deering/Mogul max MTU indication */
  31.             cp = put16(cp,0);
  32.             cp = put16(cp,icmp->args.mtu);
  33.         } else
  34.             cp = put32(cp,0L);
  35.         break;
  36.     case ICMP_PARAM_PROB:
  37.         *cp++ = icmp->args.pointer;
  38.         *cp++ = 0;
  39.         cp = put16(cp,0);
  40.         break;
  41.     case ICMP_REDIRECT:
  42.         cp = put32(cp,icmp->args.address);
  43.         break;
  44.     case ICMP_ECHO:
  45.     case ICMP_ECHO_REPLY:
  46.     case ICMP_TIMESTAMP:
  47.     case ICMP_TIME_REPLY:
  48.     case ICMP_INFO_RQST:
  49.     case ICMP_INFO_REPLY:
  50.         cp = put16(cp,icmp->args.echo.id);
  51.         cp = put16(cp,icmp->args.echo.seq);
  52.         break;
  53.     default:
  54.         cp = put32(cp,0L);
  55.         break;
  56.     }
  57.     /* Compute checksum, and stash result */
  58.     checksum = cksum(NULLHEADER,bp,len_p(bp));
  59.     cp = &bp->data[2];
  60.     cp = put16(cp,checksum);
  61.  
  62.     return bp;
  63. }
  64. /* Pull off ICMP header */
  65. int
  66. ntohicmp(icmp,bpp)
  67. struct icmp *icmp;
  68. struct mbuf **bpp;
  69. {
  70.     char icmpbuf[8];
  71.  
  72.     if(icmp == (struct icmp *)NULL)
  73.         return -1;
  74.     if(pullup(bpp,icmpbuf,8) != 8)
  75.         return -1;
  76.     icmp->type = icmpbuf[0];
  77.     icmp->code = icmpbuf[1];
  78.     switch(icmp->type){
  79.     case ICMP_DEST_UNREACH:
  80.         /* Retrieve Deering/Mogul MTU value */
  81.         if(icmp->code == ICMP_FRAG_NEEDED)
  82.             icmp->args.mtu = get16(&icmpbuf[6]);
  83.         break;
  84.     case ICMP_PARAM_PROB:
  85.         icmp->args.pointer = icmpbuf[4];
  86.         break;
  87.     case ICMP_REDIRECT:
  88.         icmp->args.address = get32(&icmpbuf[4]);
  89.         break;
  90.     case ICMP_ECHO:
  91.     case ICMP_ECHO_REPLY:
  92.     case ICMP_TIMESTAMP:
  93.     case ICMP_TIME_REPLY:
  94.     case ICMP_INFO_RQST:
  95.     case ICMP_INFO_REPLY:
  96.         icmp->args.echo.id = get16(&icmpbuf[4]);
  97.         icmp->args.echo.seq = get16(&icmpbuf[6]);
  98.         break;
  99.     }
  100.     return 0;
  101. }
  102.  
  103.