Jump to content

Converter IPv4 inteiro em xxx.xxx.xxx.xxx


Fernando Mercês

Recommended Posts

  • 9 months later...

Fala Brother,

Eu vi teu código em C aqui em cima, e comecei a pensar em fazer a operação reversa (ip => int). Uma coisa foi levando a outra, e no fim eu fiz isso. =D

Pra o código funcionar:

  1. Cola esse código em um arquivo de nome ip2int.c
  2. Compila com - gcc -o ip2int ip2int.c
  3. Cria um link simbólico - ln -s ip2int int2ip
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 
 *
 * Se precisar testar o programa
 * O inteiro 3232235521 gera o IP 192.168.0.1
 *
 */

int main(int argc, unsigned char **argv){

  // Como usar o programa
  if(argc != 2){
    printf("Uso:\n\nip2int: <ip address>\nint2ip: <inteiro>\n");
    return 1;
  }

  // Basename
  const char *exename = strrchr(argv[0], '/');
  if (exename)
    // skip past the last /
    ++exename;   
  else
    exename = argv[0];

  if(strcmp(exename,"int2ip")==0){  // Se o nome do binario for int2ip
    int i = atoi(argv[1]);
  
    printf("%d.%d.%d.%d\n",
    (i>>24) & 0xff,
    (i>>16) & 0xff,
    (i>>8) & 0xff,
    i & 0xff);
  }
  else if (strcmp(exename,"ip2int")==0){  // Se o nome do binario for ip2int
    const char *sourceString = argv[1];
    unsigned short len=0;
    unsigned char  cnt=0,cnt1=0,i,buf[5];
    unsigned int output = 0, oct = 0;
             
    len=strlen(sourceString);
    for(i=0;i<len;i++) {
      if(sourceString[i]!='.'){
        buf[cnt++] =sourceString[i];
      }
      if(sourceString[i]=='.' || i==len-1){
        buf[cnt]='\0';
        cnt=0;
        oct=atoi(buf);
        output = output<<8;
        output |= oct;
        if(oct>255){
          printf("IP address invalido - %u\n",oct);
          return 1;
        }
      }
    }
    printf("%u\n",output);
  } else {
    printf("Tenha certeza que o binario tenha o nome ip2int\ne crie um link simbolico para ele chamado int2ip."); // Se o nome do binario for qualquer outra coisa diferente
  }
  return 0;
}

Se vc chamar ./ip2int 192.168.0.1   , ele cospe 3232235521.

Se vc chamar ./int2ip 3232235521  , ele cospe 192.168.0.1

Compartilhando...  =D

Abs!

Link to comment
Share on other sites

  • 4 months later...

Olá @Baracat,

Um dica para simplificar o parsing do IP é utilizand o sscanf():

$ ./ip2int 192.168.0.1
192.168.0.1 -> 3232235521

Segue o código:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
	if (argc != 2) {
		printf ("Use: %s <IP>", argv[0]);
		return 0;
	}

	unsigned int ip[4];

	if (sscanf(argv[1], "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) != 4) {
		puts ("Invalid IP format (xxx.xxx.xxx.xxx).");
		return -1;
	}

	printf ("%s -> %u", argv[1],
			(ip[0] << 24) +
			(ip[1] << 16) +
			(ip[2] << 8) +
			(ip[3])
		);

	return 0;
}

 

Porém já existem funções espeçificas para fazer o que estamos tentando fazer:

https://www.tutorialspoint.com/unix_sockets/ip_address_functions.htm

Abraços

Link to comment
Share on other sites

Ao usar conversores "%d" não estão verificando se o valor é negativo ou superior a 255... Que tal:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

static int str2ip4 ( char *, uint32_t * );

int main ( int argc, char *argv[] )
{
  uint32_t ip;

  if ( ! *++argv )
  {
    fprintf ( stderr, "Usage: %s ipv4string\n", * ( argv - 1 ) );
    return EXIT_FAILURE;
  }

  if ( ! str2ip4 ( *argv, &ip ) )
  {
    fputs ( "ERROR: Invalid IPv4 string.\n", stderr );
    return EXIT_FAILURE;
  }

  // ESSA extensão (o 1$ e o 2$ nos conversores) é do GCC!!!
  printf ( "%1$s -> %2$" PRIu32 " (%2$#" PRIx32 ")\n", *argv, ip );

  return EXIT_SUCCESS;
}

int str2ip4 ( char *s, uint32_t *ip )
{
  char *p, *q, *r, *t;
  int count;
  unsigned long n;

  p = strdup ( s ); // para garantir que estamos trabalhando com uma cópia
  // que possa ser escrita.

  *ip = 0;
  q = p;
  t = strchr ( q, '.' );

  if ( t )
    *t++ = '\0';

  count = 1;

  while ( q )
  {
    if ( ! isdigit ( *q ) )
    {
      free ( p );
      return 0;
    }

    r = NULL;
    n = strtoul ( q, &r, 10 );

    if ( errno == ERANGE || n > 255 || *r )
    {
      free ( p );
      return 0; // falha!
    }

    *ip <<= 8;
    *ip |= ( uint8_t ) n;

    q = t;

    if ( t )
    {
      count++;
      t = strchr ( q, '.' );

      if ( t )
        *t++ = '\0';
    }
  }

  free ( p );

  return count == 4;
}

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...