Azinix

compcrypt.c

Go to the documentation of this file.
00001 /** \file compress.c]
00002 
00003   \brief Implements compression and decompression
00004 
00005 ******************************************************************************/
00006 
00007 #include "evl.h"
00008 #include "cryp.h"
00009 
00010 /**AutomaticStart*************************************************************/
00011 
00012 /*---------------------------------------------------------------------------*/
00013 /* Static function prototypes                                                */
00014 /*---------------------------------------------------------------------------*/
00015 
00016 static Cryp_Aes_t *computeAes (void **functionStatePtr, void *functionArgument);
00017 static void swap (Evl_Manager_t *mgr, Pkt_ProcessPkt_t *pp, void **functionStatePtr, void *functionArgument);
00018 static void printPayload (Evl_Manager_t *mgr, Pkt_ProcessPkt_t *pp, void **functionStatePtr, void *functionArgument);
00019 static void morphSrcIp (Evl_Manager_t *mgr, Pkt_ProcessPkt_t *pp, void **functionStatePtr, void *functionArgument);
00020 
00021 /**AutomaticEnd***************************************************************/
00022 
00023 /**
00024   * \brief Compress/decompress a packet - changes argument, assumes
00025   * enough memory has been allocated in the packet itself.  Leaves
00026   * only the ethernet header uncompressed.  Using the LZO algorithm on 
00027   * a single packet at a time.
00028   *
00029   *     function prototype action->ucodeFunction( mgr, pp, & action->ucodeFunctionState );
00030   */
00031 
00032 int
00033 Ucode_CompressDecompress (Pkt_EthernetHdr_t * pkt,
00034               int length, bool doCompress)
00035 {
00036   char tmpbuf[1518];        /// \todo replace by maximum sized header
00037   int newLength = 1518;
00038   char *payload = ((char *) pkt) + sizeof (Pkt_EthernetHdr_t);
00039   int payloadLength = length - sizeof (Pkt_EthernetHdr_t);
00040 
00041   memcpy (tmpbuf, payload, payloadLength);
00042   if (doCompress == true)
00043     {
00044       /// \todo commented out because of linker problems
00045       // compress( tmpbuf, & newLength, payload, payloadLength );
00046     }
00047   else
00048     {
00049       /// \todo commented out because of linker problems
00050       // uncompress( tmpbuf, & newLength, payload, payloadLength );
00051     }
00052   memcpy (payload, tmpbuf, newLength);
00053 
00054   return newLength + sizeof (Pkt_EthernetHdr_t);
00055 }
00056 
00057 
00058 /**
00059   * \brief Decompress a packet.
00060   */
00061 
00062 int
00063 Ucode_Decompress (Evl_Manager_t * mgr,
00064           Pkt_ProcessPkt_t * pp, void **functionStatePtr)
00065 {
00066   Pkt_EthernetHdr_t *pkt = pp->pkt;
00067   int length = pp->length;
00068   if (pkt->type == Pkt_L3ProtComp_c)
00069     {
00070       int result = Ucode_CompressDecompress (pkt, length, false);
00071       pkt->type = Pkt_L3ProtIp_c;
00072     }
00073   else
00074     {
00075       // nothing to do here
00076       return length;
00077     }
00078 }
00079 
00080 
00081 /**
00082   * \brief Compress a packet.
00083   *
00084   * Assuming packet is IP - in particular we set a new ethernet
00085   * type field to denote the packet is compressed, and to revert
00086   *     we must know what the orig type was.  (Perhaps we can play tricks
00087   * with setting a single bit?)
00088   */
00089 
00090 int
00091 Ucode_Compress (Evl_Manager_t * mgr,
00092         Pkt_ProcessPkt_t * pp, void **functionStatePtr)
00093 {
00094   Pkt_EthernetHdr_t *pkt = pp->pkt;
00095   int length = pp->length;
00096   /// \todo choosing this size to ensure no overruns.
00097   /// 
00098   /// will change with jumbo frames.
00099   /// see discussion about max increase in pkt size with lzo here
00100   /// http://www.oberhumer.com/opensource/lzo/lzofaq.php
00101   char tmpbuf[2048];
00102   memcpy (tmpbuf, pkt, length);
00103   int newLength =
00104     Ucode_CompressDecompress ((Pkt_EthernetHdr_t *) tmpbuf, length, true);
00105   if (newLength >= length)
00106     {
00107       // do nothing
00108       return length;
00109     }
00110   else
00111     {
00112       char *pktPayload = ((char *) pkt) + sizeof (Pkt_EthernetHdr_t);
00113       char *tmpBufPayload = ((char *) tmpbuf) + sizeof (Pkt_EthernetHdr_t);
00114       memcpy (pktPayload, tmpBufPayload,
00115           newLength - sizeof (Pkt_EthernetHdr_t));
00116       pkt->type = Pkt_L3ProtComp_c; // to mark it as compressed
00117       return newLength;
00118     }
00119 }
00120 
00121 
00122 /**
00123   * \brief  Encrypt a packet. 
00124   *
00125   * Only for Ip packets.  Keeps header intact, does aes on payload.  Not going
00126   * to encrypt payload shorter than 16 bytes.
00127   *
00128   * Returns 1 on succ encrypt, 0 on payload being too short.
00129   * 
00130   */
00131 
00132 void
00133 Ucode_Crypto (Cryp_Aes_t * aes, Pkt_ProcessPkt_t * pp, boolean doEncrypt)
00134 {
00135   Pkt_EthernetHdr_t *anEthpkt = pp->pkt;
00136   assert (Pkt_EthernetReadL3Type (anEthpkt) == Pkt_L3ProtIp_c);
00137   int length = pp->length;
00138 
00139   Pkt_IpHdr_t *ip = Pkt_EthernetExtractIp (anEthpkt);
00140   char *payload = Pkt_IpExtractPayload (ip);
00141   int bytesToEncode = length - (payload - (char *) anEthpkt);
00142 
00143   if (doEncrypt == true)
00144     {
00145       Cryp_AesEncrypt (payload, payload, bytesToEncode, aes);
00146     }
00147   else
00148     {
00149       Cryp_AesDecrypt (payload, payload, bytesToEncode, aes);
00150     }
00151 }
00152 
00153 
00154 /**
00155   * \brief  Encrypt a packet. 
00156   * 
00157   */
00158 
00159 void
00160 Ucode_EncryptPkt (Evl_Manager_t * mgr,
00161           Pkt_ProcessPkt_t * pp,
00162           void **functionStatePtr, void *functionArgument)
00163 {
00164   Pkt_EthernetHdr_t *pkt = pp->pkt;
00165   int length = pp->length;
00166 
00167   Cryp_Aes_t *aes = computeAes (functionStatePtr, functionArgument);
00168 
00169   Ucode_Crypto (aes, pp, true);
00170   return;
00171 }
00172 
00173 
00174 /**
00175   * \brief Get the aes structure from key.
00176   */
00177 
00178 static Cryp_Aes_t *
00179 computeAes (void **functionStatePtr, void *functionArgument)
00180 {
00181   st_table *hash = (st_table *) * functionStatePtr;
00182   if (hash == NIL (st_table))
00183     {
00184       hash = st_init_table (st_ptrcmp, st_ptrhash);
00185       *functionStatePtr = hash;
00186     }
00187   Cryp_Aes_t *aes;
00188   char *key = (char *) functionArgument;
00189   if (!st_lookup (hash, (char *) key, (char **) &aes))
00190     {
00191       aes = Cryp_AesAlloc (key);
00192     }
00193   return aes;
00194 }
00195 
00196 /**
00197   * \brief  Decrypt a packet. 
00198   * 
00199   */
00200 
00201 void
00202 Ucode_DecryptPkt (Evl_Manager_t * mgr,
00203           Pkt_ProcessPkt_t * pp,
00204           void **functionStatePtr, void *functionArgument)
00205 {
00206   Pkt_EthernetHdr_t *pkt = pp->pkt;
00207   int length = pp->length;
00208   Cryp_Aes_t *aes = computeAes (functionStatePtr, functionArgument);
00209   Ucode_Crypto (aes, pp, false);
00210   return;
00211 }
00212 
00213 /**
00214   * \brief  Decrypt a packet. 
00215   *
00216   * Directly calls the function Ucode_DecryptPkt - we need to do it this
00217   * way to be able to export the name decrypt to the sheel
00218   * 
00219   */
00220 
00221 int
00222 decrypt (Evl_Manager_t * mgr,
00223      Pkt_ProcessPkt_t * pp,
00224      void **functionStatePtr, void *functionArgument)
00225 {
00226   Ucode_DecryptPkt (mgr, pp, functionStatePtr, functionArgument);
00227   return 0; 
00228 }
00229 
00230 
00231 /**
00232   * \brief  Encrypt a packet. 
00233   *
00234   * Directly calls the function Ucode_EncryptPkt - we need to do it this
00235   * way to be able to export the name encrypt to the shell
00236   * 
00237   */
00238 
00239 int
00240 encrypt ( Evl_Manager_t * mgr,
00241       Pkt_ProcessPkt_t * pp,
00242       void **functionStatePtr, 
00243       void *functionArgument)
00244 {
00245   Ucode_EncryptPkt (mgr, pp, functionStatePtr, functionArgument);
00246   return 0; 
00247 }
00248 
00249 
00250 /** \brief Swap first two payload bytes, used for testing */
00251 
00252 static void
00253 swap (Evl_Manager_t * mgr,
00254       Pkt_ProcessPkt_t * pp, void **functionStatePtr, void *functionArgument)
00255 {
00256   char *payload = ((char *) pp->pkt) + 54;
00257   char tmp = *payload;
00258   *payload = *(payload + 1);
00259   *(payload + 1) = tmp;
00260 }
00261 
00262 
00263 /** \brief print payload, packet assumed to be IP, used for testing */
00264 
00265 static void
00266 printPayload (Evl_Manager_t * mgr,
00267           Pkt_ProcessPkt_t * pp,
00268           void **functionStatePtr, void *functionArgument)
00269 {
00270   char *payload = ((char *) pp->pkt) + 54;
00271   printf ("byte 0 = %c, byte 1 = %c; mesg %s\n", *payload, *(payload + 1),
00272       (char *) functionArgument);
00273 }
00274 
00275 
00276 /** \brief Change source IP, used for testing */
00277 
00278 static void
00279 morphSrcIp (Evl_Manager_t * mgr,
00280         Pkt_ProcessPkt_t * pp,
00281         void **functionStatePtr, void *functionArgument)
00282 {
00283   Pkt_IpHdr_t *ip = ((char *) pp->pkt) + 14;
00284   ip->sourceIp = 0;
00285 }