(root)/
glibc-2.38/
inet/
ether_aton_r.c
       1  /* Copyright (C) 1996-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <ctype.h>
      19  #include <stdlib.h>
      20  #include <netinet/ether.h>
      21  #include <netinet/if_ether.h>
      22  
      23  
      24  struct ether_addr *
      25  ether_aton_r (const char *asc, struct ether_addr *addr)
      26  {
      27    size_t cnt;
      28  
      29    for (cnt = 0; cnt < 6; ++cnt)
      30      {
      31        unsigned int number;
      32        char ch;
      33  
      34        ch = _tolower (*asc++);
      35        if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f'))
      36  	return NULL;
      37        number = isdigit (ch) ? (ch - '0') : (ch - 'a' + 10);
      38  
      39        ch = _tolower (*asc);
      40        if ((cnt < 5 && ch != ':') || (cnt == 5 && ch != '\0' && !isspace (ch)))
      41  	{
      42  	  ++asc;
      43  	  if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f'))
      44  	    return NULL;
      45  	  number <<= 4;
      46  	  number += isdigit (ch) ? (ch - '0') : (ch - 'a' + 10);
      47  
      48  	  ch = *asc;
      49  	  if (cnt < 5 && ch != ':')
      50  	    return NULL;
      51  	}
      52  
      53        /* Store result.  */
      54        addr->ether_addr_octet[cnt] = (unsigned char) number;
      55  
      56        /* Skip ':'.  */
      57        ++asc;
      58      }
      59  
      60    return addr;
      61  }
      62  libc_hidden_def (ether_aton_r)