ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

asn1_enc.c
Go to the documentation of this file.
00001 
00008 /*
00009  * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without modification,
00013  * are permitted provided that the following conditions are met:
00014  *
00015  * 1. Redistributions of source code must retain the above copyright notice,
00016  *    this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright notice,
00018  *    this list of conditions and the following disclaimer in the documentation
00019  *    and/or other materials provided with the distribution.
00020  * 3. The name of the author may not be used to endorse or promote products
00021  *    derived from this software without specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00024  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00025  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00026  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00027  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00028  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00031  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00032  * OF SUCH DAMAGE.
00033  *
00034  * Author: Christiaan Simons <christiaan.simons@axon.tv>
00035  */
00036 
00037 #include "lwip/opt.h"
00038 
00039 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
00040 
00041 #include "lwip/snmp_asn1.h"
00042 
00049 void
00050 snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed)
00051 {
00052   if (length < 0x80U)
00053   {
00054     *octets_needed = 1;
00055   }
00056   else if (length < 0x100U)
00057   {
00058     *octets_needed = 2;
00059   }
00060   else
00061   {
00062     *octets_needed = 3;
00063   }
00064 }
00065 
00076 void
00077 snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed)
00078 {
00079   if (value < 0x80UL)
00080   {
00081     *octets_needed = 1;
00082   }
00083   else if (value < 0x8000UL)
00084   {
00085     *octets_needed = 2;
00086   }
00087   else if (value < 0x800000UL)
00088   {
00089     *octets_needed = 3;
00090   }
00091   else if (value < 0x80000000UL)
00092   {
00093     *octets_needed = 4;
00094   }
00095   else
00096   {
00097     *octets_needed = 5;
00098   }
00099 }
00100 
00109 void
00110 snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed)
00111 {
00112   if (value < 0)
00113   {
00114     value = ~value;
00115   }
00116   if (value < 0x80L)
00117   {
00118     *octets_needed = 1;
00119   }
00120   else if (value < 0x8000L)
00121   {
00122     *octets_needed = 2;
00123   }
00124   else if (value < 0x800000L)
00125   {
00126     *octets_needed = 3;
00127   }
00128   else
00129   {
00130     *octets_needed = 4;
00131   }
00132 }
00133 
00141 void
00142 snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed)
00143 {
00144   s32_t sub_id;
00145   u8_t cnt;
00146 
00147   cnt = 0;
00148   if (ident_len > 1)
00149   {
00150     /* compressed prefix in one octet */
00151     cnt++;
00152     ident_len -= 2;
00153     ident += 2;
00154   }
00155   while(ident_len > 0)
00156   {
00157     ident_len--;
00158     sub_id = *ident;
00159 
00160     sub_id >>= 7;
00161     cnt++;
00162     while(sub_id > 0)
00163     {
00164       sub_id >>= 7;
00165       cnt++;
00166     }
00167     ident++;
00168   }
00169   *octets_needed = cnt;
00170 }
00171 
00180 err_t
00181 snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type)
00182 {
00183   u16_t plen, base;
00184   u8_t *msg_ptr;
00185 
00186   plen = 0;
00187   while (p != NULL)
00188   {
00189     base = plen;
00190     plen += p->len;
00191     if (ofs < plen)
00192     {
00193       msg_ptr = (u8_t*)p->payload;
00194       msg_ptr += ofs - base;
00195       *msg_ptr = type;
00196       return ERR_OK;
00197     }
00198     p = p->next;
00199   }
00200   /* p == NULL, ofs >= plen */
00201   return ERR_ARG;
00202 }
00203 
00212 err_t
00213 snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length)
00214 {
00215   u16_t plen, base;
00216   u8_t *msg_ptr;
00217 
00218   plen = 0;
00219   while (p != NULL)
00220   {
00221     base = plen;
00222     plen += p->len;
00223     if (ofs < plen)
00224     {
00225       msg_ptr = (u8_t*)p->payload;
00226       msg_ptr += ofs - base;
00227 
00228       if (length < 0x80)
00229       {
00230         *msg_ptr = (u8_t)length;
00231         return ERR_OK;
00232       }
00233       else if (length < 0x100)
00234       {
00235         *msg_ptr = 0x81;
00236         ofs += 1;
00237         if (ofs >= plen)
00238         {
00239           /* next octet in next pbuf */
00240           p = p->next;
00241           if (p == NULL) { return ERR_ARG; }
00242           msg_ptr = (u8_t*)p->payload;
00243         }
00244         else
00245         {
00246           /* next octet in same pbuf */
00247           msg_ptr++;
00248         }
00249         *msg_ptr = (u8_t)length;
00250         return ERR_OK;
00251       }
00252       else
00253       {
00254         u8_t i;
00255 
00256         /* length >= 0x100 && length <= 0xFFFF */
00257         *msg_ptr = 0x82;
00258         i = 2;
00259         while (i > 0)
00260         {
00261           i--;
00262           ofs += 1;
00263           if (ofs >= plen)
00264           {
00265             /* next octet in next pbuf */
00266             p = p->next;
00267             if (p == NULL) { return ERR_ARG; }
00268             msg_ptr = (u8_t*)p->payload;
00269             plen += p->len;
00270           }
00271           else
00272           {
00273             /* next octet in same pbuf */
00274             msg_ptr++;
00275           }
00276           if (i == 0)
00277           {
00278             /* least significant length octet */
00279             *msg_ptr = (u8_t)length;
00280           }
00281           else
00282           {
00283             /* most significant length octet */
00284             *msg_ptr = (u8_t)(length >> 8);
00285           }
00286         }
00287         return ERR_OK;
00288       }
00289     }
00290     p = p->next;
00291   }
00292   /* p == NULL, ofs >= plen */
00293   return ERR_ARG;
00294 }
00295 
00307 err_t
00308 snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value)
00309 {
00310   u16_t plen, base;
00311   u8_t *msg_ptr;
00312 
00313   plen = 0;
00314   while (p != NULL)
00315   {
00316     base = plen;
00317     plen += p->len;
00318     if (ofs < plen)
00319     {
00320       msg_ptr = (u8_t*)p->payload;
00321       msg_ptr += ofs - base;
00322 
00323       if (octets_needed == 5)
00324       {
00325         /* not enough bits in 'value' add leading 0x00 */
00326         octets_needed--;
00327         *msg_ptr = 0x00;
00328         ofs += 1;
00329         if (ofs >= plen)
00330         {
00331           /* next octet in next pbuf */
00332           p = p->next;
00333           if (p == NULL) { return ERR_ARG; }
00334           msg_ptr = (u8_t*)p->payload;
00335           plen += p->len;
00336         }
00337         else
00338         {
00339           /* next octet in same pbuf */
00340           msg_ptr++;
00341         }
00342       }
00343       while (octets_needed > 1)
00344       {
00345         octets_needed--;
00346         *msg_ptr = (u8_t)(value >> (octets_needed << 3));
00347         ofs += 1;
00348         if (ofs >= plen)
00349         {
00350           /* next octet in next pbuf */
00351           p = p->next;
00352           if (p == NULL) { return ERR_ARG; }
00353           msg_ptr = (u8_t*)p->payload;
00354           plen += p->len;
00355         }
00356         else
00357         {
00358           /* next octet in same pbuf */
00359           msg_ptr++;
00360         }
00361       }
00362       /* (only) one least significant octet */
00363       *msg_ptr = (u8_t)value;
00364       return ERR_OK;
00365     }
00366     p = p->next;
00367   }
00368   /* p == NULL, ofs >= plen */
00369   return ERR_ARG;
00370 }
00371 
00383 err_t
00384 snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value)
00385 {
00386   u16_t plen, base;
00387   u8_t *msg_ptr;
00388 
00389   plen = 0;
00390   while (p != NULL)
00391   {
00392     base = plen;
00393     plen += p->len;
00394     if (ofs < plen)
00395     {
00396       msg_ptr = (u8_t*)p->payload;
00397       msg_ptr += ofs - base;
00398 
00399       while (octets_needed > 1)
00400       {
00401         octets_needed--;
00402         *msg_ptr = (u8_t)(value >> (octets_needed << 3));
00403         ofs += 1;
00404         if (ofs >= plen)
00405         {
00406           /* next octet in next pbuf */
00407           p = p->next;
00408           if (p == NULL) { return ERR_ARG; }
00409           msg_ptr = (u8_t*)p->payload;
00410           plen += p->len;
00411         }
00412         else
00413         {
00414           /* next octet in same pbuf */
00415           msg_ptr++;
00416         }
00417       }
00418       /* (only) one least significant octet */
00419       *msg_ptr = (u8_t)value;
00420       return ERR_OK;
00421     }
00422     p = p->next;
00423   }
00424   /* p == NULL, ofs >= plen */
00425   return ERR_ARG;
00426 }
00427 
00437 err_t
00438 snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident)
00439 {
00440   u16_t plen, base;
00441   u8_t *msg_ptr;
00442 
00443   plen = 0;
00444   while (p != NULL)
00445   {
00446     base = plen;
00447     plen += p->len;
00448     if (ofs < plen)
00449     {
00450       msg_ptr = (u8_t*)p->payload;
00451       msg_ptr += ofs - base;
00452 
00453       if (ident_len > 1)
00454       {
00455         if ((ident[0] == 1) && (ident[1] == 3))
00456         {
00457           /* compressed (most common) prefix .iso.org */
00458           *msg_ptr = 0x2b;
00459         }
00460         else
00461         {
00462           /* calculate prefix */
00463           *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]);
00464         }
00465         ofs += 1;
00466         if (ofs >= plen)
00467         {
00468           /* next octet in next pbuf */
00469           p = p->next;
00470           if (p == NULL) { return ERR_ARG; }
00471           msg_ptr = (u8_t*)p->payload;
00472           plen += p->len;
00473         }
00474         else
00475         {
00476           /* next octet in same pbuf */
00477           msg_ptr++;
00478         }
00479         ident_len -= 2;
00480         ident += 2;
00481       }
00482       else
00483       {
00484 /* @bug:  allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression??  */
00485         /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
00486         return ERR_ARG;
00487       }
00488       while (ident_len > 0)
00489       {
00490         s32_t sub_id;
00491         u8_t shift, tail;
00492 
00493         ident_len--;
00494         sub_id = *ident;
00495         tail = 0;
00496         shift = 28;
00497         while(shift > 0)
00498         {
00499           u8_t code;
00500 
00501           code = (u8_t)(sub_id >> shift);
00502           if ((code != 0) || (tail != 0))
00503           {
00504             tail = 1;
00505             *msg_ptr = code | 0x80;
00506             ofs += 1;
00507             if (ofs >= plen)
00508             {
00509               /* next octet in next pbuf */
00510               p = p->next;
00511               if (p == NULL) { return ERR_ARG; }
00512               msg_ptr = (u8_t*)p->payload;
00513               plen += p->len;
00514             }
00515             else
00516             {
00517               /* next octet in same pbuf */
00518               msg_ptr++;
00519             }
00520           }
00521           shift -= 7;
00522         }
00523         *msg_ptr = (u8_t)sub_id & 0x7F;
00524         if (ident_len > 0)
00525         {
00526           ofs += 1;
00527           if (ofs >= plen)
00528           {
00529             /* next octet in next pbuf */
00530             p = p->next;
00531             if (p == NULL) { return ERR_ARG; }
00532             msg_ptr = (u8_t*)p->payload;
00533             plen += p->len;
00534           }
00535           else
00536           {
00537             /* next octet in same pbuf */
00538             msg_ptr++;
00539           }
00540         }
00541         /* proceed to next sub-identifier */
00542         ident++;
00543       }
00544       return ERR_OK;
00545     }
00546     p = p->next;
00547   }
00548   /* p == NULL, ofs >= plen */
00549   return ERR_ARG;
00550 }
00551 
00561 err_t
00562 snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw)
00563 {
00564   u16_t plen, base;
00565   u8_t *msg_ptr;
00566 
00567   plen = 0;
00568   while (p != NULL)
00569   {
00570     base = plen;
00571     plen += p->len;
00572     if (ofs < plen)
00573     {
00574       msg_ptr = (u8_t*)p->payload;
00575       msg_ptr += ofs - base;
00576 
00577       while (raw_len > 1)
00578       {
00579         /* copy raw_len - 1 octets */
00580         raw_len--;
00581         *msg_ptr = *raw;
00582         raw++;
00583         ofs += 1;
00584         if (ofs >= plen)
00585         {
00586           /* next octet in next pbuf */
00587           p = p->next;
00588           if (p == NULL) { return ERR_ARG; }
00589           msg_ptr = (u8_t*)p->payload;
00590           plen += p->len;
00591         }
00592         else
00593         {
00594           /* next octet in same pbuf */
00595           msg_ptr++;
00596         }
00597       }
00598       if (raw_len > 0)
00599       {
00600         /* copy last or single octet */
00601         *msg_ptr = *raw;
00602       }
00603       return ERR_OK;
00604     }
00605     p = p->next;
00606   }
00607   /* p == NULL, ofs >= plen */
00608   return ERR_ARG;
00609 }
00610 
00611 #endif /* LWIP_SNMP */

Generated on Mon May 28 2012 04:35:52 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.