inet_addr関数


inet_addr関数
今日はプログラミングでinet_を使いましたaddr関数は、あまり詳しくなく、資料を探して、以下のように整理しました.inet_addrの機能は、ipアドレス文字列を整数値に変換することです.一般的なIPアドレス列フォーマットは、'a.b.c.d'が4つのセグメントに分かれている.ただし、1、2または3段に分かれたフォーマットもあります.次はWIN 2 K下inetを見てみましょうaddr関数のソースコード:
unsigned long PASCAL
inet_addr(
    IN const char *cp
    )
{
        register unsigned long val, base, n;
        register char c;
        unsigned long parts[4], *pp = parts;

        WS_ENTER( "inet_addr", (PVOID)cp, NULL, NULL, NULL );
again:
        /*
         * Collect number up to ``.''.
         * Values are specified as for C:
         * 0x=hex, 0=octal, other=decimal.
         */
        val = 0; base = 10;  //                  。
        if (*cp == '0') {    //0X       ;0      ;      
                base = 8, cp++;
                if (*cp == 'x' || *cp == 'X')
                        base = 16, cp++;
    }
    
        //           IP            
        while (c = *cp) {
                if (isdigit(c)) {                         //    ,            
                        val = (val * base) + (c - '0');   //  , W2K      BUG,    8     
                        cp++;                             //     8、9  ;     XP    。
                        continue;
                }
                if (base == 16 && isxdigit(c)) {  //  16   ,     ‘a’~ 'f'  
                        val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
                        cp++;
                        continue;
                }
                break;
        }
       //  ‘.’ ,          。
        if (*cp == '.') {
                /*
                 * Internet format:
                 *      a.b.c.d
                 *      a.b.c   (with c treated as 16-bits)
                 *      a.b     (with b treated as 24 bits)
                 */
                /* GSS - next line was corrected on 8/5/89, was 'parts + 4' */
                if (pp >= parts + 3) {                   //  ‘.’  ,        3  。
                        WS_EXIT( "inet_addr", -1, TRUE );//     3 ‘.’
                        return ((unsigned long) -1);     // W2K          ‘.’   IP      
                }                                        //  XP      。
                *pp++ = val, cp++;
                goto again;
        }

        /*
         * Check for trailing characters.//    ,    ,       
         */                              //   0       ,    。       
        if (*cp && !isspace(*cp)) {
                WS_EXIT( "inet_addr", -1, TRUE );
                return (INADDR_NONE);
        }
        *pp++ = val;
        /*
         * Concoct the address according to
         * the number of parts specified.
         */
        n = (unsigned long)(pp - parts);
        switch ((int) n) {

        case 1:                         /* a -- 32 bits */  //     a ,       。
                val = parts[0];
                break;

        case 2:                         /* a.b -- 8.24 bits */    //     a.b ,     XX  XX XX XX
                if ((parts[0] > 0xff) || (parts[1] > 0xffffff)) { //                           --  --------
                    WS_EXIT( "inet_addr", -1, TRUE );             //                           a       b   
                    return(INADDR_NONE);
                }
                val = (parts[0] << 24) | (parts[1] & 0xffffff);
                break;

        case 3:                         /* a.b.c -- 8.8.16 bits *///  3  a.b.c ,     XX  XX   XX XX
                if ((parts[0] > 0xff) || (parts[1] > 0xff) ||     //                            --  --   -----
                    (parts[2] > 0xffff)) {                        //                            a    b     c
                    WS_EXIT( "inet_addr", -1, TRUE );
                    return(INADDR_NONE);
                }
                val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
                        (parts[2] & 0xffff);
                break;

        case 4:          /* a.b.c.d -- 8.8.8.8 bits *///  4  a.b.c.d ,     XX  XX   XX   XX
                if ((parts[0] > 0xff) || (parts[1] > 0xff) ||        //               --  --   --   --
                    (parts[2] > 0xff) || (parts[3] > 0xff)) {        //               a    b    c    d
                    WS_EXIT( "inet_addr", -1, TRUE );
                    return(INADDR_NONE);
                }
                val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
                      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
                break;

        default:
                WS_EXIT( "inet_addr", -1, TRUE );
                return (INADDR_NONE);
        }
        val = htonl(val);
        WS_EXIT( "inet_addr", val, FALSE );
        return (val);
}