##############################################################################
#                                                                            #
# IAR ARM ANSI C/C++ Compiler V4.11A/W32               20/Jul/2004  18:58:46 #
# Copyright 1999-2004 IAR Systems. All rights reserved.                      #
#                                                                            #
#    Cpu mode        =  arm                                                  #
#    Endian          =  little                                               #
#    Stack alignment =  4                                                    #
#    Source file     =  C:\medusa\icmp.c                                     #
#    Command line    =  -I "C:\Program Files\IAR Systems\Embedded Workbench  #
#                       4.0\ARM\INC\" -lc C:\medusa\Debug\List\ -la          #
#                       C:\medusa\Debug\List\ -o C:\medusa\Debug\Obj\ -s2    #
#                       --no_cse --no_unroll --no_inline --no_code_motion    #
#                       --no_tbaa --no_clustering --no_scheduling --debug    #
#                       --cpu_mode arm --endian little --cpu ARM7TDMI-S      #
#                       --stack_align 4 -e --fpu None                        #
#                       "-D_DLIB_CONFIG_FILE=C:\Program Files\IAR            #
#                       Systems\Embedded Workbench                           #
#                       4.0\ARM\LIB\dl4tpannl8n.h" C:\medusa\icmp.c          #
#    List file       =  C:\medusa\Debug\List\icmp.lst                        #
#    Object file     =  C:\medusa\Debug\Obj\icmp.r79                         #
#                                                                            #
#                                                                            #
##############################################################################

C:\medusa\icmp.c
      1          #include "archinc.h"
      2          #include "cli.h"
      3          #include "strutil.h"
      4          #include "zarlink.h"
      5          #include "icmp.h"
      6          
      7          #include <stdio.h>
      8          #include <stdlib.h>
      9          
     10          typedef struct arpRequest_t {
     11            unsigned short hwType;
     12            unsigned short protocolType;
     13            unsigned char hwLen;
     14            unsigned char protocolLen;         // set to 4 for IPv4
     15            unsigned short operation;          // 1 = request; 2 = reply
     16            unsigned char senderEthMacAddr[6]; // should be filled in by switch
     17            unsigned char senderIpAddr[4];     // 4 bytes for IPv4
     18            unsigned char targetEthMacAddr[6]; // need not be filled for request (set zero)
     19            unsigned char targetIpAddr[4];     // 4 bytes for IPv4
     20            } arpRequest_t;
     21          
     22          static unsigned char arpReqFrameData[64];
     23          
     24          /*
     25           * The structure of an ethernet header is: 
     26           * | Source MAC (6 bytes)  | Dest MAC (6 bytes) | type (2 bytes) |
     27           *
     28           * A type of 0x0800 indicates an IP packet
     29           *
     30           * The ethernet trailer is a 32-bit CRC
     31           */
     32          
     33          static int initArpPacket(unsigned short opcode, char *pPktData, char *pSenderIp, char *pTargetIp)
     34          {
     35            int i;
     36            arpRequest_t * pArpReq = (arpRequest_t *)(arpReqFrameData + 14);
     37          
     38            if (pPktData == NULL)
     39              return -1; 
     40          
     41            /*
     42             * Ethernet MAC layer data (offsets 0-13)
     43             */
     44          
     45            for(i=0;i<6;i++)
     46              arpReqFrameData[i] = 0xff; // broadcast
     47          
     48            zarlinkCpuMacAddrGet(&(arpReqFrameData[6]));
     49            swapMac(&(arpReqFrameData[6]));
     50          
     51            // 0x0806 = ARP
     52            arpReqFrameData[12] = 0x08;
     53            arpReqFrameData[13] = 0x06;
     54          
     55            /*
     56             * ARP (ICMP) data (offsets 14-64)
     57             */
     58          
     59            pArpReq->hwType = byteSwap16(0x0001); // hwtype = ethernet
     60            pArpReq->protocolType = byteSwap16(0x0800); // prottype = IPv4 (0x0800)
     61            pArpReq->hwLen = 0x06;
     62            pArpReq->protocolLen = 0x04;
     63          
     64            // opcode = request (0x0001), reply (0x0002)
     65            pArpReq->operation = byteSwap16(opcode);
     66          
     67            if (pSenderIp != NULL) {
     68              zarlinkCpuMacAddrGet(&(pArpReq->senderEthMacAddr[0]));
     69              swapMac(&(pArpReq->senderEthMacAddr[0]));
     70              for(i=0;i<4;i++) {
     71                pArpReq->senderIpAddr[i] = pSenderIp[i];
     72                }
     73              }
     74            else {
     75              for(i=0;i<4;i++) {
     76                pArpReq->senderIpAddr[i] = 0x00;
     77                }
     78              }
     79          
     80            if (pTargetIp != NULL) {
     81              zarlinkCpuMacAddrGet(&(pArpReq->targetEthMacAddr[0]));
     82              swapMac(&(pArpReq->targetEthMacAddr[0]));
     83              for(i=0;i<4;i++) {
     84                pArpReq->targetIpAddr[i] = pTargetIp[i];
     85                }
     86              }
     87            else {
     88              for(i=0;i<4;i++) {
     89                pArpReq->targetIpAddr[i] = 0x00;
     90                }
     91              }
     92          
     93            return 0;
     94          }
     95          
     96          static int initArpRequest(char *pPktData, char *pArpIp)
     97          {
     98            return initArpPacket((unsigned short)0x0001, pPktData, pArpIp, NULL);
     99          }
    100          
    101          static int initArpReply(char *pPktData, char *pArpIp)
    102          {
    103            return initArpPacket((unsigned short)0x0002, pPktData, NULL, pArpIp);
    104          }
    105          
    106          int icmpArpRequestSend(char * pArpReqIpAddr, int port) 
    107          {
    108            if (pArpReqIpAddr == NULL)
    109              return -1;
    110          
    111            if (initArpRequest(arpReqFrameData, pArpReqIpAddr) == 0) {
                                      ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    112              return zarlinkEthFrameWrite(64, arpReqFrameData, port); 
    113              }
    114          
    115            return -1; // shouldn't get here
    116          }
    117          
    118          int icmpArpReplySend(char * pArpReplyIpAddr, int port) 
    119          {
    120            if (pArpReplyIpAddr == NULL)
    121              return -1;
    122          
    123            if (initArpReply(arpReqFrameData, pArpReplyIpAddr) == 0) {
                                    ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    124              return zarlinkEthFrameWrite(64, arpReqFrameData, port); 
    125              }
    126          
    127            return -1; // shouldn't get here
    128          }
    129          
    130          static unsigned char arpIp[4];
    131          
    132          static int sendArpHandler(int argc, char * argv[], int flags)
    133          {
    134            int retVal = -1;
    135            int sendPort;
    136            char * pOutBuf;
    137            int bufLen;
    138          
    139            if (argc < 4)
    140              return retVal;
    141          
    142            pOutBuf = clicharGetOutputBuffer(&bufLen);
    143          
    144            sendPort = (int)strtol(argv[2], (char **)NULL, 16);
    145          
    146            if (parseDottedQuadV4(argv[3], arpIp) == 0) {
    147              switch(*argv[1]) {
    148                case 'q':
    149                case 'Q':
    150                  sprintf(pOutBuf, "%s: sending arp request on port [%02x] for IP %02d %02d %02d %02d\r\n", 
    151                    argv[0], sendPort, arpIp[0], arpIp[1], arpIp[2], arpIp[3]); 
    152                  clicharSendOutputBuffer(pOutBuf, bufLen);
    153                  retVal = icmpArpRequestSend(arpIp, sendPort);
                                                     ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    154                  break;
    155                case 'p':
    156                case 'P':
    157                case 'g':
    158                case 'G':
    159                  sprintf(pOutBuf, "%s: sending arp reply (grat) on port [%02x] for IP %02d %02d %02d %02d\r\n", 
    160                    argv[0], sendPort, arpIp[0], arpIp[1], arpIp[2], arpIp[3]); 
    161                  clicharSendOutputBuffer(pOutBuf, bufLen);
    162                  retVal = icmpArpReplySend(arpIp, sendPort);
                                                   ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    163                  break;
    164                default:
    165                  break;
    166                } // switch
    167              }
    168          
    169            return retVal;
    170          }
    171          
    172          
    173          int icmpInit(void)
    174          {
    175            cliRegisterCommand("arp", sendArpHandler, "arp [re(q)uest | re(p)ly, (g)rat] [port] [IP Addr]");
    176            return 0;
    177          }  

   Maximum stack usage in bytes:

     Function           CSTACK
     --------           ------
     icmpArpReplySend      12
     icmpArpRequestSend    12
     icmpInit               4
     initArpPacket         28
     initArpReply          12
     initArpRequest        12
     sendArpHandler        48


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     arpReqFrameData                  64
     initArpPacket                   392
     initArpRequest                   36
     initArpReply                     36
     icmpArpRequestSend               80
     icmpArpReplySend                 80
     arpIp                             4
     sendArpHandler                  412
     icmpInit                         40
     ??DataTable9                      4
     ?<Constant "%s: sending arp reque...">
                                      68
     ?<Constant "%s: sending arp reply...">
                                      76
     ?<Constant "arp">                 4
     ?<Constant "arp [re(q)uest | re(p...">
                                      52
      Others                         132

 
 1 200 bytes in segment CODE
   200 bytes in segment DATA_C
    68 bytes in segment DATA_Z
    12 bytes in segment INITTAB
 
 1 080 bytes of CODE  memory (+ 132 bytes shared)
   200 bytes of CONST memory
    68 bytes of DATA  memory

Errors: none
Warnings: 4
