inet_aton конвертирует 010.000.000.001 неправильно?

У меня проблемы с inet_aton конвертировать сетевой адрес. Код ниже работает нормально, чтобы преобразовать адрес 10.0.0.1

char *x1;
struct sockaddr_in si_other;
inet_aton("10.0.0.1", &si_other.sin_addr);
printf("si_other.sin_addr =%lu\n",si_other.sin_addr);
x1 = inet_ntoa(si_other.sin_addr);
printf("x1=%s\n",x1);

Это выводит:

si_other.sin_addr =16777226
x1=10.0.0.01

Пока проблем нет. Тем не менее, функция работает странно, когда 010.000.000.001 передается

char *x2;
struct sockaddr_in si_other2;
inet_aton("010.000.000.001", &si_other2.sin_addr);
printf("si_other2.sin_addr =%lu\n",si_other2.sin_addr);
x2 = inet_ntoa(si_other2.sin_addr);
printf("x2=%s\n",x2);

выходы:

si_other.sin_addr2 =16777224
x2=8.0.0.01

Функция отлично работает, когда 192.168.0.1 а также 192.168.000.001 пройдены.

Может кто-нибудь объяснить мне, в чем проблема и как я могу решить проблему? (примечание: мне нужно передать IP-адрес как 010.000.000.001 в моем коде)

1 ответ

Решение

Ведущий 0 интерпретируется как указание на восьмеричное число. 010 (октав) == 8 (дек). Вам нужно изменить ввод inet_aton чтобы избежать этого, или преобразовать это самостоятельно другим способом.

const char *str = "010.000.000.001";
inet_aton(str[0] == '0' ? str+1:str, &si_other.sin_addr);

Это самое простое решение, но было бы лучше исправить что угодно (snprintf?) сначала создает строку, чтобы избежать путаницы.

(В настоящее время решение не будет работать с рядом пограничных случаев, включая "001.0.0.1", "0xF.0.0.1", "1" и многие другие действительные адреса IPv4).

Вы можете тривиально "нормализовать" свой ввод, используя sscanf, даже если вы не можете контролировать, как он генерируется в первую очередь (хотя это действительно должно быть ошибкой, на мой взгляд):

#include <stdio.h>
#include <stdlib.h>

int main() {
  const char *str="010.020.030.040";
  int parts[4];
  sscanf(str, "%d.%d.%d.%d", parts+0, parts+1, parts+2, parts+3);
  char *out = NULL;
  asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
  printf("%s\n", out);
  free(out);
  return 0;
}
Другие вопросы по тегам