valida tengo saber entre direcciones direccion diferencia con compatible comparacion como codigo cantidad c string

tengo - direccion ipv6 valida



Determine si una cadena es una dirección IPv4 válida en C (13)

Aquí está el inicio de una función en la que he estado trabajando, aunque no está completa, puede provocar ideas o comentarios. El pensamiento detrás de la función es;

  1. Verifique que el puntero o cadena de caracteres que se pasó sea una dirección IPv4 sin puerto que use su tamaño mínimo / máximo, cuántos puntos en la cadena y si el carácter de dos puntos: existe o no.
  2. Si la cadena no es IPv4 con o sin un puerto, verifique si la cadena es IPv6, si no es IPv6, el formato IP no se reconoce porque aún no está implementado.

Creo que depende de la profundidad con la que desea profundizar en el problema, la profundidad con la que desea comprender qué problemas pueden surgir.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <arpa/inet.h> int isIP(char *ip) { char *data_ptr = ip; // Create a pointer to passed data int orig_str_size = 0; // Create an int to hold passed data size int str_index = 0; // Create an int to iterate individual ip characters int dot_count = 0; // Create an int to check for the number of dots // Count the number of characters in data_ptr while (*data_ptr++ != ''/0''){ orig_str_size++; } if(orig_str_size <= 0) // If nothing { printf("Get a grip, ip is empty/n/n"); exit(0); } else // If within IPv4 size range if(orig_str_size >= 7 && orig_str_size <= INET_ADDRSTRLEN) { char *data1_ptr = ip; // Create a pointer to passed data printf("Within IPv4 range, %i characters in length/n/n", orig_str_size); // Count the number of dots in the string, 3 for IPv4 for(str_index; str_index < orig_str_size; str_index++) { if(data1_ptr[str_index] == ''.''){ dot_count++; } } // If theres 3 dots, while ignoring dots, check each char is a digit if(dot_count == 3) { printf("There''s three dots in the string/n/n"); data1_ptr = ip; str_index = 0; // Iterate the string char by char for(str_index; str_index < orig_str_size; str_index++) { // Ignoring dots if(data1_ptr[str_index] != ''.'') { // If isdigit() is happy its a digit and isalpha() happy not alphabetic if(isdigit(data1_ptr[str_index]) && !isalpha(data1_ptr[str_index])) { printf("Digit found and is not alphabetic/n/n"); continue; } else if(!isdigit(data1_ptr[str_index]) && isalpha(data1_ptr[str_index])) { printf("Not a recognised IPv4 address, character detected in string/n/n"); exit(0); } } } return 0; } } else // If IPv6 if(orig_str_size > 0 && orig_str_size > INET_ADDRSTRLEN && orig_str_size <= INET6_ADDRSTRLEN) { printf("Within IPv6 range %i/n/n", orig_str_size); return 0; } else { printf("Unknown target format, the format you provided as a target is not implemented/n/n"); exit(0); } }

TCP / IP Internetworking

RFC791 - Protocolo de Internet - https://tools.ietf.org/html/rfc791

El manual de CISCO Internetworking http://docwiki.cisco.com/wiki/Internetworking_Technology_Handbook

El modelo de referencia de interconexión de sistemas abiertos http://docwiki.cisco.com/wiki/Internetworking_Basics#Open_Systems_Interconnection_Reference_Model

CISCO Solución de problemas de redes TCP / IP https://www.cisco.com/en/US/docs/internetworking/troubleshooting/guide/tr1907.pdf

¿Cuál es el número de puerto de red TCP / IP más grande permitido para IPv4?

¿Cuál sería una buena manera de determinar si una cadena contiene una dirección IPv4? ¿Debo usar isdigit() ?


Creo que debajo del fragmento de código C debería funcionar

bool validate_ip4(const char* buffer) { if (NULL == buffer) return false; register const char* pos = buffer; register unsigned char ch = *pos; register unsigned short count = 0; while (ch != NULL) { if (!((ch >= ''0'' && ch <= ''9'') || ch == ''.'')) return false; if (ch == ''.'') if (++count > 3) return false; ch = *++pos; } if (count == 3 && *--pos != ''.'') return true; return false; }


Daré la solución "no quiero dos problemas":

#include <string.h> int isIp_v4( char* ip){ int num; int flag = 1; int counter=0; char* p = strtok(ip,"."); while (p && flag ){ num = atoi(p); if (num>=0 && num<=255 && (counter++<4)){ flag=1; p=strtok(NULL,"."); } else{ flag=0; break; } } return flag && (counter==3); }

EDITAR: es posible que strtok no esté a salvo de hilos (créditos para Adam Rosenfield)


En la url / uri rfc 3986, la dirección ipv4 de la forma aumentada de Backus-Naur (ABNF) se define como:

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet dec-octet = DIGIT ; 0-9 / %x31-39 DIGIT ; 10-99 / "1" 2DIGIT ; 100-199 / "2" %x30-34 DIGIT ; 200-249 / "25" %x30-35 ; 250-255

Implementé el cheque con regexp en la siguiente forma:

// Although the RFC says ipv6 octects like 001 are not valid, it would be risky // not to accept those #define decoct "([01]?[0-9]?[0-9]|2[0-4][0-0]|25[0-5])" #define ipv4 "(" decoct "//." decoct "//." decoct "//." decoct ")"


Esta es una rutina que escribí hace un tiempo para un sistema integrado que generó varios patrones sospechosos en una red. Como tal, no utiliza absolutamente ninguna cosa sofisticada como las bibliotecas de red o incluso las bibliotecas estándar de C, prefiriendo mantenerse alejado de todas las cosas modernas como la tokenización de cadenas y las bibliotecas de expresión regular (estremecedor) :-) Para ese fin, es adecuado para casi cualquier entorno en el que pudieras encontrarte, y fue increíblemente rápido.

Aunque, si estás en un entorno que tiene algo como checkIp4Addess() , te sugiero que uses eso en su lugar. Es una indicación de las cosas que a veces tienes que aguantar cuando haces cosas incrustadas (aunque es una solución real).

int isValidIp4 (char *str) { int segs = 0; /* Segment count. */ int chcnt = 0; /* Character count within segment. */ int accum = 0; /* Accumulator for segment. */ /* Catch NULL pointer. */ if (str == NULL) return 0; /* Process every character in string. */ while (*str != ''/0'') { /* Segment changeover. */ if (*str == ''.'') { /* Must have some digits in segment. */ if (chcnt == 0) return 0; /* Limit number of segments. */ if (++segs == 4) return 0; /* Reset segment values and restart loop. */ chcnt = accum = 0; str++; continue; }

/* Check numeric. */ if ((*str < ''0'') || (*str > ''9'')) return 0; /* Accumulate and check segment. */ if ((accum = accum * 10 + *str - ''0'') > 255) return 0; /* Advance other segment specific stuff and continue loop. */ chcnt++; str++; } /* Check enough segments and enough characters in last segment. */ if (segs != 3) return 0; if (chcnt == 0) return 0; /* Address okay. */ return 1; }


Este es mi intento con una programación de C de nivel muy bajo (en realidad se usa en uno de mis programas para un microcontrolador PIC) No utiliza la librería string.h. No usa punteros, ya que este compilador que estoy usando no funciona bien con ellos, de todos modos usted podría usarlos. Teniendo esto en cuenta y definiendo previamente una variable para manejar el búfer de datos entrantes como este:

#define isdigit(x) isamong(x,"0123456789") char IPACK_Buff[IPACK_SIZE]; // Check if string is a valid IP int IPACK_is_valid_ip(int len) { int i = 0; int j = 0; int NumDots = 0; char number[4] = "000/0"; // Check first char is numeric if (!isdigit(IPACK_Buff[0])) return 0; for (i = 0 ; i< len; i++) { if (isdigit(IPACK_Buff[i])) { number[j] = IPACK_Buff[i]; j++; if (j>3) return 0; } else if (IPACK_Buff[i] == ''.'') { if (atof(number)> 255) return 0; memset(number, ''/0'', 4); j = 0; NumDots++; if(NumDots>3) return 0; } } if (NumDots == 3) { return 1; } else return 0; }//

Espero que esta función os ayude a todos. Nuevamente, tenga en cuenta el bajo nivel que esta función está programada antes de criticar.


Hazlo desde cero de esta manera. Este código contiene herramientas para verificar si la cadena contiene la dirección IP IPv4.

#define MAX_HEX_NUMBER_COUNT 8 int ishexdigit(char ch) { if((ch>=''0''&&ch<=''9'')||(ch>=''a''&&ch<=''f'')||(ch>=''A''&&ch<=''F'')) return(1); return(0); } int IsIp6str(char *str) { int hdcount=0; int hncount=0; int err=0; int packed=0; if(*str=='':'') { str++; if(*str!='':'') return(0); else { packed=1; hncount=1; str++; if(*str==0) return(1); } } if(ishexdigit(*str)==0) { return(0); } hdcount=1; hncount=1; str++; while(err==0&&*str!=0) { if(*str=='':'') { str++; if(*str=='':'') { if(packed==1) err=1; else { str++; if(ishexdigit(*str)||*str==0&&hncount<MAX_HEX_NUMBER_COUNT) { packed=1; hncount++; if(ishexdigit(*str)) { if(hncount==MAX_HEX_NUMBER_COUNT) { err=1; } else { hdcount=1; hncount++; str++; } } } else { err=1; } } } else { if(!ishexdigit(*str)) { err=1; } else { if(hncount==MAX_HEX_NUMBER_COUNT) { err=1; } else { hdcount=1; hncount++; str++; } } } } else { if(ishexdigit(*str)) { if(hdcount==4) err=1; else { hdcount++; str++; } } else err=1; } } if(hncount<MAX_HEX_NUMBER_COUNT&&packed==0) err=1; return(err==0); } int IsIp4str(char *str) { int nnumber=0; int value=0; int err=0; if(*str>=''0''&&*str<=''9'') { value=*str-''0''; str++; } else return(0); nnumber=1; while(err==0&&*str!=0) { if(*str>=''0''&&*str<=''9'') { if(255/value>=10) { value*=10; if(255-value>=(*str-''0'')) { value+=(*str-''0''); str++; } else err=1; } else err=1; } else { if(*str==''.'') { str++; if(*str>=''0''&&*str<=''9'') { if(nnumber==4) err=1; else { if(*str==''0'') { *str++; if(*str!=''.''&&*str!=0) err=1; else { nnumber++; value=0; } } else { nnumber++; value=*str-''0''; str++; } } } else { err=1; } } else if(*str!=0) err=1; } } if(nnumber!=4) err=1; return(err==0); }

Prueba de la función IsIp4str (char * str) si la cadena contiene el formato de dirección de la versión cuatro de la dirección IP. Prueba de función IsIp6str (char * str) si la cadena contiene el formato de dirección de la versión seis de la dirección IP.

Las funciones IsIp4str (char * str) e IsIp6str (char * str) devuelven true si string str contiene una dirección IP o false si string str no contiene una dirección IP.

Si necesita verificar si la cadena contiene el formato IPv6 de la dirección IP, puede hacerlo con la función IsIp6str (char * str). Funciona de la misma manera que


Hice una pregunta similar para C ++ . Deberías poder usar una versión ligeramente modificada (para C) de lo que se me ocurrió entonces.

bool isValidIpAddress(char *ipAddress) { struct sockaddr_in sa; int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr)); return result != 0; }

Deberá #include <arpa/inet.h> para usar la función inet_pton() .

Actualización basada en comentarios a la pregunta: si desea saber si una cadena de estilo C contiene una dirección IP, debe combinar las dos respuestas que se dieron hasta el momento. Use una expresión regular para encontrar patrones que coincidan aproximadamente con una dirección IP, luego use la función de arriba para verificar la coincidencia para ver si es el negocio real.


Necesitaba averiguar si la cadena entrante "contiene" una dirección IP válida y devolver un puntero a la parte de la cadena entrante que es la dirección IP válida, si es así. Si no, devuelve un puntero nulo.

Aquí está el código que parece funcionar, aunque todavía no está bien probado, lo escribí y lo probé rápidamente. No agregué una verificación todavía para limitar los números a los valores de un byte, pero sí verifico que estén limitados a números de tres dígitos.

int IsDigit(char ch) { int is_digit = 0; if ( ch >= ''0'' && ch <= ''9'' ) { is_digit = 1; } return is_digit; } #define FIND_IP_START 0 #define FIND_IP_DIGIT 1 #define FIND_IP_DIG_OR_DEC 2 #define FIND_IP_DECIMAL 3 #define FIND_IP_DIG_OR_END 4 #define FIND_IP_END 5 #define FIND_IP_DONE 6 char * StringContainsValidIpAddress(char * input_buf_pointer) { char * pos = input_buf_pointer; int octets = 0; int digits = 0; int state = FIND_IP_START; char * ip_string = 0; char ch = *pos; while ( (ch != NULL) && (state != FIND_IP_DONE) ) { switch ( state ) { case FIND_IP_START: if ( IsDigit(ch) ) { ip_string = pos; //potential start of ip string digits = 1; // first digit octets = 1; // of first octet state = FIND_IP_DIG_OR_DEC; } break; case FIND_IP_DIGIT: if ( IsDigit(ch) ) { digits = 1; // first digit octets++; // of next octet if ( octets == 4 ) { state = FIND_IP_DIG_OR_END; } else { state = FIND_IP_DIG_OR_DEC; } } else { // Start over state = FIND_IP_START; } break; case FIND_IP_DIG_OR_DEC: // Here we are looking for another digit // of the same octet or the decimal between // octets. if (ch == ''.'') { state = FIND_IP_DIGIT; } else if ( IsDigit(ch) ) { digits++; // next digit if ( digits == 3 ) { state = FIND_IP_DECIMAL; } } else { // Start over state = FIND_IP_START; } break; case FIND_IP_DECIMAL: if (ch == ''.'') { state = FIND_IP_DIGIT; } break; case FIND_IP_DIG_OR_END: // Here we are looking for another digit // of the same octet or the end (which could // be a space or CR or LF or really any // non-digit). if ( IsDigit(ch) ) { digits++; // next digit if ( digits == 3 ) { state = FIND_IP_END; } } else { *pos = 0; // Null terminate the IP address string state = FIND_IP_DONE; } break; case FIND_IP_END: if ( !IsDigit(ch) ) { *pos = 0; // Null terminate the IP address string state = FIND_IP_DONE; } break; case FIND_IP_DONE: break; default: break; } // Fetch the next character ch = *++pos; } if (state == FIND_IP_DONE) { return ip_string; } else { return 0; } }



inet_addr () es mucho mejor que inet_aton () para la verificación de direcciones IPv4 de representación de notación de número y punto.


// you can even use the v value array to return the unsigned int // version of the IP if desired in an unsigned int reference. bool isvalidip(const char * s) { char t[8]; int p = 0; int v[8]; int numnum = 0; for (int i = 0; i < (int) strlen(s); i++) { char c = s[i]; int cgood = 0; if (c >= ''0'' && c <= ''9'' && p < 4) { t[p++] = c; t[p] = 0; cgood++; continue; } if (p == 4) return false; if (c == ''.'') { if (!p) return false; v[numnum++] = atoi(t); p = 0; cgood++; continue; } if (!cgood) return false; // not a valid character if (numnum > 4) return false; // we have a lot of dots.... } v[numnum++] = atoi(t); // we did not have a dot, we had a NULL..... if (numnum != 4) return false; // we must have had 4 valid numbers.... for (int i = 0; i < 4; i++) { if (v[i] < 0 || v[i] > 255) return false; // octet values out-of-range } return true; //we good.. }


int validateIP4Dotted(const char *s) { int len = strlen(s); if (len < 7 || len > 15) return 0; char tail[16]; tail[0] = 0; unsigned int d[4]; int c = sscanf(s, "%3u.%3u.%3u.%3u%s", &d[0], &d[1], &d[2], &d[3], tail); if (c != 4 || tail[0]) return 0; for (int i = 0; i < 4; i++) if (d[i] > 255) return 0; return 1; }