Jump to content
Fernando Mercês

Converter IPv4 inteiro em xxx.xxx.xxx.xxx

Recommended Posts

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!

  • Agradecer 1
  • Curtir 2

Share this post


Link to post
Share on other sites

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

  • l33t 1

Share this post


Link to post
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;
}

 

Edited by fredericopissarra

Share this post


Link to post
Share on other sites

Claro, outra maneira de fazer é usando getaddrinfo(). Vantagem: suporta IPv6 tb. Desvantagens: Há tentariva de resolver nome; vários registros podem ser retornados (inclusive IPv4 mapeado em IPv6)....

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...