By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,676 Members | 1,669 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,676 IT Pros & Developers. It's quick & easy.

Convert an ip address to long value

P: n/a
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?

-kyle

Jan 31 '06 #1
Share this Question
Share on Google+
65 Replies


P: n/a
kyle.tk wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?


Too lazy to look right now; consider

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

#define NUM_OCTETTS 4

int iptoul (const char *ip, unsigned long *plong)
{
char *next = NULL;
const char *curr = ip;
unsigned long tmp;
int i, err = 0;

*plong = 0;
for (i = 0; i < NUM_OCTETTS; i++) {
tmp = strtoul(curr, &next, 10);
if (tmp >= 256
|| (tmp == 0 && next == curr))
{
err++;
break;
}
*plong = (*plong << 8) + tmp;
curr = next + 1;
}

if (err) {
return 1;
}
else {
return 0;
}
}

int main (void)
{
const char *ip = "124.15.22.102";
unsigned long ret;

if (0 == iptoul(ip, &ret))
printf("%s -> %lu\n", ip, ret);

return 0;
}

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Jan 31 '06 #2

P: n/a
Michael Mair wrote:
kyle.tk wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?

Too lazy to look right now; consider

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

#define NUM_OCTETTS 4

int iptoul (const char *ip, unsigned long *plong)
{
char *next = NULL;
const char *curr = ip;
unsigned long tmp;
int i, err = 0;

*plong = 0;
for (i = 0; i < NUM_OCTETTS; i++) {
tmp = strtoul(curr, &next, 10);
if (tmp >= 256
|| (tmp == 0 && next == curr))
{
err++;
break;
}

Forgot the obvious one:
if (*next != '.' && i != (NUM_OCTETTS-1)) {
err++;
break;
} *plong = (*plong << 8) + tmp;
curr = next + 1;
}

if (err) {
return 1;
}
else {
return 0;
}
}

int main (void)
{
const char *ip = "124.15.22.102";
unsigned long ret;

if (0 == iptoul(ip, &ret))
printf("%s -> %lu\n", ip, ret);

return 0;
}

Cheers
Michael

--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Jan 31 '06 #3

P: n/a


kyle.tk wrote On 01/31/06 15:27,:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?


You could use sscanf(). Unfortunately, it's hard
to persuade sscanf() to reject things like "123.0.0.-1"
or " 127. 0. 0. 1".

Another possibility would be to use isdigit() to
check the first character of each field and then strtoul()
to convert it, then check that strtoul() stopped on a '.'
(or on a '\0' the final time). You might also check that
the stopping point wasn't too far from the start, so as
to reject "000000000000127.0.0.000000000000000001".

--
Er*********@sun.com

Feb 1 '06 #4

P: n/a
kyle.tk wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
That \0 is not necessary.
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
Well, let's work through this loop.
Start: i = 11, j = 10.
Iter 1: j => 9. ip[9] == '.' so i => 9.
Iter 2: j => 8. i => 8. tmp[8] = ip[8] = '1'.
Iter 3: j => 7. ip[7] == '.' so i => 6.
Iter 4: j => 6. i => 5. tmp[5] = ip[6] = '8'.
Iter 5: j => 5. i => 4. tmp[4] = ip[5] = '6'.
Iter 6: j => 4. i => 3. tmp[3] = ip[4] = '1'.
Iter 7: j => 3. ip[3] = '.', so i => 3.
Iter 8: j => 2. i => 2. tmp[2] = ip[2] = '2'.
Iter 9: j => 1. i => 1. tmp[1] = ip[1] = '9'.
Iter10: j => 0. i => 0. tmp[0] = ip[0] = '1'.
Iter11: j => -1. Undefined behaviour, reading ip[-1].
Maybe will try and write to tmp[-1].

So you end up with tmp = "192168001000" and maybe having
written a buffer overflow before the start of tmp.

Hopefully it's now clear that your loop structure is pretty
weak and error-prone. A much better approach here is
to read forwards through ip, computing as you go, you
don't need to create a new array.
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];


tmp[0] is '1'. '1' * 100 will probably give you a value of 4900.
You mean to write: (tmp[0] - '0') * 100 , etc.

Feb 1 '06 #5

P: n/a

Michael Mair wrote:
kyle.tk wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?


Too lazy to look right now; consider

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

#define NUM_OCTETTS 4

int iptoul (const char *ip, unsigned long *plong)
{
char *next = NULL;
const char *curr = ip;
unsigned long tmp;
int i, err = 0;

*plong = 0;
for (i = 0; i < NUM_OCTETTS; i++) {
tmp = strtoul(curr, &next, 10);
if (tmp >= 256
|| (tmp == 0 && next == curr))
{
err++;
break;
}
*plong = (*plong << 8) + tmp;
curr = next + 1;
}

if (err) {
return 1;
}
else {
return 0;
}
}

int main (void)
{
const char *ip = "124.15.22.102";
unsigned long ret;

if (0 == iptoul(ip, &ret))
printf("%s -> %lu\n", ip, ret);

return 0;
}

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.


Alright, after looking at that post I came up with this. I didn't use
yours verbatim because I have not yet implemented the stroul function.

Heres what I have got now. Critique?

unsigned long iptol(const char *ip){
unsigned long value = 0; /* Total Value */
unsigned char ocet = 0; /* Ocet Value */
int i = strlen(ip) - 1; /* Index in ip */
int m = 1; /* Ocet multiplier */
int j;
for (j=0; j < 4; j++){
while ( ip[i] != '.' && ip[i] != '\0' ){
ocet += m * (ip[i] - 48);
m *= 10;
i--;
}
value += (ocet << (8 * j));
ocet = 0;
m = 1;
i--;
};
return value;
}
-kyle

Feb 1 '06 #6

P: n/a

"kyle.tk" <ky*****@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?


Yes, this is an alternate method, using more string processing. It compiles
and works for DJGPP and OW1.3:
#include <stdio.h>
#include <string.h>

unsigned long iptoul(char *ip)
{
char i,*tmp;
unsigned long val=0, cvt;

tmp=strtok(ip,".");
for (i=0;i<4;i++)
{
sscanf(tmp,"%lu",&cvt);
val<<=8;
val|=(unsigned char)cvt;
tmp=strtok(NULL,".");
}
return(val);
}

int main(void)
{

char *ip="124.15.22.102";

unsigned long ret;

printf("%s\n",ip);
ret=iptoul(ip);
printf("%08lx\n",ret);
return(0);
}
Rod Pemberton
Feb 1 '06 #7

P: n/a
kyle.tk wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}
I don't see any any conversion from character to digits (via a "- '0'"
kind of operation.) So I can't see how this is possibly supposed to
work. Furthermore, it is possible and legal to specify IP addresses
in which each portion might exceed 255, and therefore might have more
than 3 digits -- its supposed to just wrap around.
int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?


This is off the top of my head:

unsigned long iptol (const char *ip) {
unsigned long ipl, b;
int i, m;
for (b = ipl = 0ul, m=4, i = 0; ; i++) {
switch (ip[i]) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
b = b*10 + ip[i] - '0';
break;
default:
ipl = (ipl << 8ul) + b;
if ('.' != ip[i] || 0==(--m)) return ipl;
b = 0;
break;
}
}
}

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Feb 1 '06 #8

P: n/a
"kyle.tk" wrote:
.... snip ...
Alright, after looking at that post I came up with this. I didn't use
yours verbatim because I have not yet implemented the stroul function.


strtoul() is a standard function. You don't need to implement it.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 1 '06 #9

P: n/a

CBFalconer wrote:

strtoul() is a standard function. You don't need to implement it.


I know it is a standard function in libc. The platform I am targeting
does not yet have a fully ported libc.

-kyle

Feb 1 '06 #10

P: n/a
kyle.tk wrote:
Michael Mair wrote:
#define NUM_OCTETTS 4

int iptoul (const char *ip, unsigned long *plong)
{
char *next = NULL;
const char *curr = ip;
unsigned long tmp;
int i, err = 0;

*plong = 0;
for (i = 0; i < NUM_OCTETTS; i++) {
tmp = strtoul(curr, &next, 10);
if (tmp >= 256
|| (tmp == 0 && next == curr))
{
err++;
break;
}
*plong = (*plong << 8) + tmp;
curr = next + 1;
}

if (err) {
return 1;
}
else {
return 0;
}
}
Alright, after looking at that post I came up with this. I didn't use
yours verbatim because I have not yet implemented the stroul function.


You don't, it's declared in <stdlib.h>
Heres what I have got now. Critique?

unsigned long iptol(const char *ip){
unsigned long value = 0; /* Total Value */
unsigned char ocet = 0; /* Ocet Value */
int i = strlen(ip) - 1; /* Index in ip */
This can fail if ip points to an empty string. But you don't need to
read
the string from right to left.
int m = 1; /* Ocet multiplier */
int j;
These are really redundant if you read the string from left to right.
for (j=0; j < 4; j++){
while ( ip[i] != '.' && ip[i] != '\0' ){
Given where i started, you're not going to encounter a '\0', so that
test is
redundant.
ocet += m * (ip[i] - 48);
'0' is more portable than a literal 48. You're condition test doesn't
check that
ip[i] is a digit, only that it's not '.', so you're conversion here is
somewhat
wreckless, even with the '0' == 48 presumption.
m *= 10;
i--;
}
value += (ocet << (8 * j));
ocet = 0;
m = 1;
i--;
};
return value;
}


If you don't care about error cases...

unsigned long iptol2(const char *ip)
{
unsigned long ul = 0;
unsigned octet = 0;
for (; *ip; ip++)
{
if ('0' <= *ip && *ip <= '9')
octet = octet * 10 + (*ip - '0');
else if (*ip == '.')
{
ul = (ul << 8) + octet;
octet = 0;
}
}
return (ul << 8) + octet;
}

--
Peter

Feb 1 '06 #11

P: n/a
Peter Nilsson wrote:
kyle.tk wrote:
Michael Mair wrote:
#define NUM_OCTETTS 4

int iptoul (const char *ip, unsigned long *plong)
{
.... snip code ...
Heres what I have got now. Critique?
.... snip code ...
If you don't care about error cases...

unsigned long iptol2(const char *ip)
{
unsigned long ul = 0;
unsigned octet = 0;
for (; *ip; ip++)
{
if ('0' <= *ip && *ip <= '9')
octet = octet * 10 + (*ip - '0');
else if (*ip == '.')
{
ul = (ul << 8) + octet;
octet = 0;
}
}
return (ul << 8) + octet;
}


Untested, but somewhat more robust IMO:

unsigned long iptoul(const char *ip) {
unsigned int octet;
int count;
unsigned long ul;

count = 0; ul = 0;
while (' ' == *ip) ip++; /* absorb leading blanks */
do {
octet = 0;
while (('0' <= *ip) && (*ip <= '9')) {
octet = 10 * octet + (*ip - '0');
ip++;
}
count++;
ul = 256 * ul + (count % 256);
if ('.' == *ip) *ip++;
} while ((count < NUM_OCTETS) &&
('0' <= *ip) && (*ip <= '9'));
return ul;
}

which also avoids std library calls, i.e. isdigit

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 1 '06 #12

P: n/a

"Eric Sosman" <er*********@sun.com> wrote in message
news:dr**********@news1brm.Central.Sun.COM...


kyle.tk wrote On 01/31/06 15:27,:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

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

/* Convert an ipv4 address to long integer */
/* "192.168.1.1" --> 3232235777 */
unsigned long iptol(char *ip){
unsigned char o1,o2,o3,o4; /* The 4 ocets */
char tmp[13] = "000000000000\0";
short i = 11; /* Current Index in tmp */
short j = (strlen(ip) - 1);
do {
if ((ip[--j] == '.')){
i -= (i % 3);
}
else {
tmp[--i] = ip[j];
}
} while (i > -1);
o1 = (tmp[0] * 100) + (tmp[1] * 10) + tmp[2];
o2 = (tmp[3] * 100) + (tmp[4] * 10) + tmp[5];
o3 = (tmp[6] * 100) + (tmp[7] * 10) + tmp[8];
o4 = (tmp[9] * 100) + (tmp[10] * 10) + tmp[11];
return (o1 * 16777216) + (o2 * 65536) + (o3 * 256) + o4;
}

int main(void){
char *ip = "124.15.22.102";
iptol(ip);
}

Any suggestions? Maybe there is a better way to do this?


You could use sscanf(). Unfortunately, it's hard
to persuade sscanf() to reject things like "123.0.0.-1"
or " 127. 0. 0. 1".

Another possibility would be to use isdigit() to
check the first character of each field and then strtoul()
to convert it, then check that strtoul() stopped on a '.'
(or on a '\0' the final time). You might also check that
the stopping point wasn't too far from the start, so as
to reject "000000000000127.0.0.000000000000000001".

--
Er*********@sun.com


Actually sscanf() is a simple and very common method. The sscanf itself
doesn't necessarily need
to validate the address. So things like

if (sscanf(hostname, "%u.%u.%u.%u",
ip[0],ip[1], ip[2],ip[3]) == 4)
{
}

are a good start.
Feb 1 '06 #13

P: n/a
CBFalconer:
Untested, but somewhat more robust IMO:
Maybe you should have tested it.
unsigned long iptoul(const char *ip) {
unsigned int octet;
int count;
unsigned long ul;

count = 0; ul = 0;
while (' ' == *ip) ip++; /* absorb leading blanks */
do {
octet = 0;
while (('0' <= *ip) && (*ip <= '9')) {
octet = 10 * octet + (*ip - '0');
ip++;
}
count++;
ul = 256 * ul + (count % 256);
"count" should be spelled "octet".
if ('.' == *ip) *ip++;
The second * is superfluous.
} while ((count < NUM_OCTETS) &&
('0' <= *ip) && (*ip <= '9'));
return ul;
}

which also avoids std library calls, i.e. isdigit


Additionally, the function returns 1.2.3.4 for any valid IP-address.
Very robust indeed. :-)

Jirka
Feb 1 '06 #14

P: n/a
Barry wrote:
.... snip ...
Actually sscanf() is a simple and very common method. The sscanf
itself doesn't necessarily need to validate the address. So things
like

if (sscanf(hostname, "%u.%u.%u.%u",
ip[0],ip[1], ip[2],ip[3]) == 4)
{
}

are a good start. From responses elsethread it appears that the OP is on embedded

systems without a full library available. If he doesn't have
strtol he certainly doesn't have the much bigger scanf interpreter.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 1 '06 #15

P: n/a
This is a bit off-topic but...

In article <44************@individual.net>
Michael Mair <Mi**********@invalid.invalid> wrote:
tmp = strtoul(curr, &next, 10);


(... which handles each of the four parts of a "10.9.8.7" style IPv4
address.)

Traditionally, each octet is allowed to be in decimal, hex, or
octal, independent of each previous octet. To match "traditional
BSD semantics", make the strtoul() call above use base 0.

Yes, this means that you can "ping 192.0xb2.031.249". No, there
is no particularly good reason to do that -- and some implementations
do not allow it (but some spammers do depend on it to hide their
"real" IP addresses).

(Traditional BSD libraries also allow the entire 32-bit address to
be given as a single number, but that requires more code, whereas
changing the last argument to strtoul() does not.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Feb 1 '06 #16

P: n/a
Chris Torek wrote:
This is a bit off-topic but...

In article <44************@individual.net>
Michael Mair <Mi**********@invalid.invalid> wrote:
tmp = strtoul(curr, &next, 10);


(... which handles each of the four parts of a "10.9.8.7" style IPv4
address.)

Traditionally, each octet is allowed to be in decimal, hex, or
octal, independent of each previous octet. To match "traditional
BSD semantics", make the strtoul() call above use base 0.

Yes, this means that you can "ping 192.0xb2.031.249". No, there
is no particularly good reason to do that -- and some implementations
do not allow it (but some spammers do depend on it to hide their
"real" IP addresses).

(Traditional BSD libraries also allow the entire 32-bit address to
be given as a single number, but that requires more code, whereas
changing the last argument to strtoul() does not.)


Thank you -- I was not aware of this bit of "evolved" semantics ;-)

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 1 '06 #17

P: n/a
Jirka Klaue wrote:
CBFalconer:
Untested, but somewhat more robust IMO:


Maybe you should have tested it.
unsigned long iptoul(const char *ip) {
unsigned int octet;
int count;
unsigned long ul;

count = 0; ul = 0;
while (' ' == *ip) ip++; /* absorb leading blanks */
do {
octet = 0;
while (('0' <= *ip) && (*ip <= '9')) {
octet = 10 * octet + (*ip - '0');
ip++;
}
count++;
ul = 256 * ul + (count % 256);


"count" should be spelled "octet".
if ('.' == *ip) *ip++;


The second * is superfluous.
} while ((count < NUM_OCTETS) &&
('0' <= *ip) && (*ip <= '9'));
return ul;
}

which also avoids std library calls, i.e. isdigit


Additionally, the function returns 1.2.3.4 for any valid IP-address.
Very robust indeed. :-)


Which proves I should have tested it, instead of being impressed by
my own infallibility at the keyboard :-) However I suspect it will
work correctly after the repairs you have pointed out (still not
tested), and will do respectable and controlled things with faulty
input and unusual systems. Which was my objective.

Thank you for the corrections. At least it was sufficiently
legible for others to follow my peculiar warped logic.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 2 '06 #18

P: n/a
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


this is an assembly 'solution' with the use of C library functions
i think it could be easyly ported to linux-gcc, windows-[c-compiler]
but has the need of >= intel 386 cpu

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams
global _main

section _TEXT public align=1 class=CODE use32

; ip_to_ul(dword* ris, dword* arr)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; p1[4], p2[4], p3[4], p4[4]
sub esp, 32 ; 5..8, 9..12, 13..16, 17..20<32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @p1 ebp-8
%define @p2 ebp-12
%define @p3 ebp-16
%define @p4 ebp-20
mov esi, [@arr]
lea eax, [@p1]
lea ebx, [@p2]
lea ecx, [@p3]
lea edx, [@p4]
push edx
push ecx
push ebx
push eax
push $i_p$i_p$i_p$i
push esi
call _sscanf
add esp, 24
cmp eax, 4
je .a1
..a0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..a1:
cmp dword[@p1], 0
jl .a0
cmp dword[@p2], 0
jl .a0
cmp dword[@p3], 0
jl .a0
cmp dword[@p4], 0
jl .a0
cmp dword[@p1], 256
jg .a0
cmp dword[@p2], 256
jg .a0
cmp dword[@p3], 256
jg .a0
cmp dword[@p4], 256
jg .a0
mov eax, dword[@p1]
shl eax, 8
add eax, dword[@p2]
shl eax, 8
add eax, dword[@p3]
shl eax, 8
add eax, dword[@p4]
mov ebx, [@ris]
mov dword[ebx], 1
..fn:
%undef @ris
%undef @arr
%undef @p1
%undef @p2
%undef @p3
%undef @p4
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret
; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]
push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams ; it should be stdout
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
Feb 2 '06 #19

P: n/a
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


this is an assembly 'solution' with the use of C library functions
i think it could be easyly ported to linux-gcc, windows-[c-compiler]
but has the need of >= intel 386 cpu

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams
global _main

section _TEXT public align=1 class=CODE use32

; ip_to_ul(dword* ris, dword* arr)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; p1[4], p2[4], p3[4], p4[4]
sub esp, 32 ; 5..8, 9..12, 13..16, 17..20<32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @p1 ebp-8
%define @p2 ebp-12
%define @p3 ebp-16
%define @p4 ebp-20
mov esi, [@arr]
lea eax, [@p1]
lea ebx, [@p2]
lea ecx, [@p3]
lea edx, [@p4]
push edx
push ecx
push ebx
push eax
push $i_p$i_p$i_p$i
push esi
call _sscanf
add esp, 24
cmp eax, 4
je .a1
..a0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..a1:
cmp dword[@p1], 0
jl .a0
cmp dword[@p2], 0
jl .a0
cmp dword[@p3], 0
jl .a0
cmp dword[@p4], 0
jl .a0
cmp dword[@p1], 256
jg .a0
cmp dword[@p2], 256
jg .a0
cmp dword[@p3], 256
jg .a0
cmp dword[@p4], 256
jg .a0
mov eax, dword[@p1]
shl eax, 8
add eax, dword[@p2]
shl eax, 8
add eax, dword[@p3]
shl eax, 8
add eax, dword[@p4]
mov ebx, [@ris]
mov dword[ebx], 1
..fn:
%undef @ris
%undef @arr
%undef @p1
%undef @p2
%undef @p3
%undef @p4
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret
; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]
push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams ; it should be stdout
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
Feb 2 '06 #20

P: n/a
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams , _isspace
global _main

section _TEXT public align=1 class=CODE use32

; unsigned decarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
decarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
..a0:
mov dl, [esi]
..a1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
lea ebx, [4*eax+eax]
sub edx, '0'
lea eax, [2*ebx]
add eax, edx
inc esi
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a4
cmp dl, 0
je .a4
mov dl, [esi]
cmp edx, '9'
jg .a4
cmp edx, '0'
jl .a4
jmp short .e0
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned hexarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
hexarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], 'x'
je .h0
cmp byte[esi], 'X'
je .h0
jmp .e0
..h0:
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, 'F'
ja .c0
cmp edx, 'A'
jb .c0
sub edx, 'A'
add edx, 10
jmp short .a2
..c0:
cmp edx, 'f'
ja .c1
cmp edx, 'a'
jb .c1
sub edx, 'a'
add edx, 10
jmp short .a2
..c1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
sub edx, '0'
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a6
cmp edx, 10
je .a6
cmp edx, '.'
je .a6
jmp short .e0
..a2:
shl eax, 4
inc esi
add eax, edx
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a6
cmp dl, 0
je .a6
mov dl, [esi]
cmp edx, 'F'
jg .a4
cmp edx, 'A'
jl .a4
jmp short .e0
..a4:
cmp edx, 'f'
jg .a5
cmp edx, 'a'
jl .a5
jmp short .e0
..a5:
cmp edx, '9'
jg .a6
cmp edx, '0'
jge .a6
jmp .e0

..a6:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret
; ip_to_ul(dword* ris, dword* arr)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; @w
sub esp, 32 ; 21..24 <32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @w ebp+24
mov esi, [@arr]
xor ebx, ebx
jmp short .c1
..c0:
inc esi
..c1:
mov bl, [esi]
push ebx
call _isspace
add esp, 4
cmp eax, 0
jne .c0

cmp bl, 0
jne .c2
..e0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..c2: ; c=1.2.3.4
mov ecx, 4
mov edx, 0
mov ebx, 0
..c3:
lea eax, [@w]
push esi
push eax
call decarr_to_u
add esp, 8
cmp esi, [@w]
jne .c4
lea eax, [@w]
push esi
push eax
call hexarr_to_u
add esp, 8
cmp esi, [@w]
je .e0

..c4:
cmp eax, 255
ja .e0
shl ebx, 8
mov esi, [@w]
add ebx, eax
cmp ecx, 1
je .c5
cmp byte[esi], '.'
jne .e0
jmp short .c6
..c5:
cmp byte[esi], ' '
je .c7
cmp byte[esi], 10
je .c7
jmp short .e0
..c6:
inc esi
dec ecx
jmp short .c3
..c7:
mov eax, [@ris]
mov dword[eax], 1
mov eax, ebx
..fn:
%undef @ris
%undef @arr
%undef @w
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret
; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]
push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
Feb 2 '06 #21

P: n/a

RSoIsCaIrLiIoA wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?


A few comments (in any language) might help.

--
Regards
Alex McDonald

Feb 2 '06 #22

P: n/a

Alex McDonald wrote:
RSoIsCaIrLiIoA wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?


A few comments (in any language) might help.


*Please* don't feed the troll...

Thanks

Vladimir

Feb 2 '06 #23

P: n/a
On Thu, 02 Feb 2006 10:52:17 +0100, RSoIsCaIrLiIoA <zz@zz.z> wrote:
cmp dword[@p1], 256
jg .a0
cmp dword[@p2], 256
jg .a0
cmp dword[@p3], 256
jg .a0
cmp dword[@p4], 256
jg .a0


this should be 255 not 256
Feb 2 '06 #24

P: n/a
On Thu, 02 Feb 2006 16:29:58 +0100, RSoIsCaIrLiIoA <zz@zz.z> wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?


i add octal (i don't know if it is right it is the first time i write
something in 'octal')

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams , _isspace
global _main

section _TEXT public align=1 class=CODE use32
; unsigned otto_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
otto_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], ' '
jne .b1
..b0:
mov eax, 0
jmp .a4
..b1:
cmp byte[esi], 10
je .b0
cmp byte[esi], 0
je .b0
cmp byte[esi], '.'
je .b0
..a0:
mov dl, [esi]
..a1:
cmp edx, '7'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
cmp edx, 0
je .a4
jmp short .e0

..a2:
shl eax, 3
sub edx, '0'
add eax, edx
inc esi
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a4
cmp dl, 0
je .a4
mov dl, [esi]
cmp edx, '7'
jg .a4
cmp edx, '0'
jl .a4
jmp short .e0
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned decarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
decarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
..a0:
mov dl, [esi]
..a1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 0
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
lea ebx, [4*eax+eax]
sub edx, '0'
lea eax, [2*ebx]
add eax, edx
inc esi
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a4
cmp dl, 0
je .a4
mov dl, [esi]
cmp edx, '9'
jg .a4
cmp edx, '0'
jl .a4
jmp short .e0
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned hexarr_to_u(char* dove, char* arr)
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
hexarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], 'x'
je .h0
cmp byte[esi], 'X'
je .h0
jmp .e0
..h0:
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, 'F'
ja .c0
cmp edx, 'A'
jb .c0
sub edx, 'A'
add edx, 10
jmp short .a2
..c0:
cmp edx, 'f'
ja .c1
cmp edx, 'a'
jb .c1
sub edx, 'a'
add edx, 10
jmp short .a2
..c1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
sub edx, '0'
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp .fn
..e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a6
cmp edx, 0
je .a6
cmp edx, 10
je .a6
cmp edx, '.'
je .a6
jmp short .e0
..a2:
shl eax, 4
inc esi
add eax, edx
dec ecx
jnz .a0

..a3: ; errore +3 digits
cmp ecx, 0
jne .a6
cmp dl, 0
je .a6
mov dl, [esi]
cmp edx, 'F'
jg .a4
cmp edx, 'A'
jl .a4
jmp short .e0
..a4:
cmp edx, 'f'
jg .a5
cmp edx, 'a'
jl .a5
jmp short .e0
..a5:
cmp edx, '9'
jg .a6
cmp edx, '0'
jge .a6
jmp .e0

..a6:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret
; ip_to_ul(dword* ris, dword* arr)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; @w
sub esp, 32 ; 21..24 <32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @w ebp+24
mov esi, [@arr]
xor ebx, ebx
jmp short .c1
..c0:
inc esi
..c1:
mov bl, [esi]
push ebx
call _isspace
add esp, 4
cmp eax, 0
jne .c0

cmp bl, 0
jne .c2
..e0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..c2: ; c=1.2.3.4
mov ecx, 4
mov edx, 0
mov ebx, 0
..c3:
cmp byte[esi], '0'
jne .b0
cmp byte[esi+1], 'x'
je .a1
cmp byte[esi+1], 'X'
jne .a2
..a1:
lea eax, [@w]
push esi
push eax
call hexarr_to_u
add esp, 8
jmp short .c4
..a2:
lea eax, [@w]
push esi
push eax
call otto_to_u
add esp, 8
jmp short .c4
..b0:
lea eax, [@w]
push esi
push eax
call decarr_to_u
add esp, 8
..c4:
cmp esi, [@w]
je .e0
cmp eax, 255
ja .e0
shl ebx, 8
mov esi, [@w]
add ebx, eax
cmp ecx, 1
je .c5
cmp byte[esi], '.'
jne .e0
jmp short .c6
..c5:
cmp byte[esi], ' '
je .c7
cmp byte[esi], 10
je .c7
jmp .e0
..c6:
inc esi
dec ecx
jmp short .c3
..c7:
mov eax, [@ris]
mov dword[eax], 1
mov eax, ebx
..fn:
%undef @ris
%undef @arr
%undef @w
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret
; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]

push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
Feb 2 '06 #25

P: n/a
On Thu, 02 Feb 2006 16:29:58 +0100, RSoIsCaIrLiIoA <zz@zz.z> wrote:
decarr_to_u:
push ebx
push edx
push esi
push ecx .e1:
cmp ecx, 3
je .e0
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0


here i have to add in here all routines
cmp edx, 0
je .a4
Feb 2 '06 #26

P: n/a
RSoIsCaIrLiIoA wrote:

On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?

Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?

00000000: be 00000051 move.l #text,r5
00000005: e8 00000005 bsr.l convert ; result in eax
0000000a: e9 00000051 br.l exit

convert:
0000000f: b3 03 move.b #3,r3
00000011: 31 d2 _30: eor.l r1,r1
00000013: 31 c0 _20: eor.l r0,r0
00000015: 8a 06 move.b (r5),r0
00000017: 46 inc.l r5
00000018: 08 c0 or.b r0,r0
0000001a: 74 25 beq.b _100
0000001c: 3c 2e cmp.b #'.',r0
0000001e: 74 17 beq.b _10
00000020: 2c 30 sub.b #'0',r0
00000022: 72 2b bcs.b _error
00000024: 3c 09 cmp.b #9,r0
00000026: 77 27 bhi.b _error
00000028: 6b d2 0a mulsq.l #10,r1,r1
0000002b: 01 c2 add.l r0,r1
0000002d: 81 fa 000000ff cmp.l #255,r1
00000033: 77 1a bhi.b _error
00000035: eb dc br.b _20
00000037: fe cb _10: dec.b r3
00000039: 72 14 bcs.b _error
0000003b: 0f ac d1 08 dsr.l #8,r1>r2
0000003f: eb d0 br.b _30
00000041: 08 db _100: or.b r3,r3
00000043: 75 0a bne.b _error
00000045: 0f ac d1 08 dsr.l #8,r1>r2
00000049: 0f c9 bswap.l r2
0000004b: 89 c8 move.l r2,r0
0000004d: f8 bclr.l #0,sr
0000004e: c3 rts.l
0000004f: f9 _error: bset.l #0,sr
00000050: c3 rts.l

00000051: 31 33 37 2e 31 39
00000057: 33 2e 36 34 2e 31
0000005d: 33 30 00 text: dc.b "137.193.64.130",0
Feb 2 '06 #27

P: n/a
Herbert Kleebauer <kl**@unibwm.de> writes:
RSoIsCaIrLiIoA wrote:

[snip]
do you like my last try?


Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?

00000000: be 00000051 move.l #text,r5
00000005: e8 00000005 bsr.l convert ; result in eax
0000000a: e9 00000051 br.l exit

[snip]

To the folks in alt.lang.asm:

"RSoIsCaIrLiIoA" is a troll, deliberately posting assembly language to
comp.lang.c. I don't know whether what he/she writes makes sense in
the context of alt.lang.asm, but if you post a followup, *please* drop
the cross-post to comp.lang.c.

Thank you.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 2 '06 #28

P: n/a
On Thu, 02 Feb 2006 16:29:58 +0100, in comp.lang.c , RSoIsCaIrLiIoA
<zz@zz.z> wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?


I don't like any of your tries - you're posting what looks like some
form of assembler to comp.lang.c. Stop that please.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Feb 2 '06 #29

P: n/a
Mark McIntyre wrote:
On Thu, 02 Feb 2006 16:29:58 +0100, in comp.lang.c , RSoIsCaIrLiIoA
<zz@zz.z> wrote:

On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:

I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.


do you like my last try?

I don't like any of your tries - you're posting what looks like some
form of assembler to comp.lang.c. Stop that please.
Mark McIntyre


I hate to be late. Assuming this was ever a valid question, how about
this? Is there a better way?

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

unsigned long
iptoul(char *ip) {
unsigned long ul = 0, t;
char *p;

do {
t = strtoul(ip, &p, 0);
ul = ul * 256 + t;
ip = p + 1;
} while (*p == '.');

return ul;
}

char *
ultoip(unsigned long ul) {
static char ip[16];
char t[16];
char *tp;
unsigned long tl;
ip[0] = '\0';

do {
tp = t;
tl = ul % 256;
ul /= 256;
if (ul) *t = '.', ++tp;
sprintf(tp, "%lu", tl);
strcat(t, ip);
strcpy(ip, t);
} while (ul);

return ip;
}

int
main(int argc, char *argv[]) {
char *ip;
unsigned long ul;
if (argc > 1)
ip = argv[1];
else
ip = "1.2.3.4";
ul = iptoul(ip);
printf("%lu, %08x\n", ul, (unsigned)ul);
puts(ultoip(ul));
return 0;
}

The theory is that really well written stuff doesn't need comments. :-)

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Feb 3 '06 #30

P: n/a

"Joe Wright" wrote:
RSoIsCaIrLiIoA wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

I hate to be late. Assuming this was ever a valid question, how about
this? Is there a better way?


there sure is a shorter way... It is up to you to figure out the converse
function of iptol yourself (aka ltoip)... try using the % operator and
shifting... ;-)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
<SNIP>

Too many #includes... tend to bloat the code ...

Here is my working example (OW1.4 but I don't find any implementation
defined stuff in it so it _is_ portable, AFAICS) which doesn't even need
_any_ lib-function for the logic, it is pure C too...:

//just for printf in main() and nothing else...
#include <stdio.h>

unsigned long iptol(char* IP) {
char* runner=IP;
unsigned int factor=1;
unsigned long temp=0;
unsigned int reset=0;

while(*runner) runner++;

while((IP - runner--)) {
if(*runner=='.') {
factor <<= 8;
reset^=reset;
runner--;
}
temp += factor * (*runner - '0') * (reset==1?10:(reset==2?100:1));
reset++;
}
return temp;
}

int main(int argc, char **argv)
{
if(argc<=1){
printf("Example: %s 10.2.3.123\n", argv[0]);
return -1;
}

printf("%x:%ld",iptol(argv[1]),iptol(argv[1]));
return 0;
}

The theory is that really well written stuff doesn't need comments. :-)


could be true :-) but I tend to say real beauty needs no decoration...

regards
John
Feb 3 '06 #31

P: n/a

"John F" wrote:
Here is my working example (OW1.4 but I don't find any implementation
defined stuff in it so it _is_ portable, AFAICS) which doesn't even need
_any_ lib-function for the logic, it is pure C too...:
the portability stuff was meant to exclude the argv[0] ... sorry...
if(argc<=1){
printf("Example: %s 10.2.3.123\n", argv[0]);
return -1;
}


this is of course _not_ portable... I simply read over it... sorry.

regards
John
Feb 3 '06 #32

P: n/a
Mark McIntyre wrote:
RSoIsCaIrLiIoA <zz@zz.z> wrote:
"kyle.tk" <ky*****@gmail.com> wrote:
I am trying to write a function to convert an ipv4 address that
is held in the string char *ip to its long value equivalent. Here
is what I have right now, but I can't seem to get it to work.


do you like my last try?


I don't like any of your tries - you're posting what looks like some
form of assembler to comp.lang.c. Stop that please.


+-------------------+ .:\:\:/:/:.
| PLEASE DO NOT F :.:\:\:/:/:.:
| FEED THE TROLLS | :=.' - - '.=:
| | '=(\ 9 9 /)='
| Thank you, | ( (_) )
| Management | /`-vvv-'\
+-------------------+ / \
| | @@@ / /|,,,,,|\ \
| | @@@ /_// /^\ \\_\
@x@@x@ | | |/ WW( ( ) )WW
\||||/ | | \| __\,,\ /,,/__
\||/ | | | jgs (______Y______)
/\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
================================================== ============

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 3 '06 #33

P: n/a
"John F" <sp**@127.0.0.1> writes:
reset^=reset;


Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0
?

Or do you just think that more is more?

Phil
--
What is it: is man only a blunder of God, or God only a blunder of man?
-- Friedrich Nietzsche (1844-1900), The Twilight of the Gods
Feb 3 '06 #34

P: n/a

kyle.tk wrote:
I am trying to write a function to convert an ipv4 address that is held
in the string char *ip to its long value equivalent. Here is what I
have right now, but I can't seem to get it to work.

[snip]

Any suggestions? Maybe there is a better way to do this?

-kyle


This example is probably a little silly, but it has the advantage of
not relying on the standard library (other than printf()). It will
handle octets in different formats (e.g., 0.255.0377.0xff) and it will
accept leading and trailing whitespace in each octet (e.g., "127. 0
..0. 1"). Whitespace embedded within the octet token ("1 27.0.0.1")
will cause the function to return 0.

Error handling is non-existent; it will not detect overflow in any of
the octets (e.g. 256.397.400.999), nor will it handle missing octets
(255.255.0). That should be relatively straightforward to fix, though.

#include <stdio.h>

typedef enum {start, lead, dec, oct, hex, tail, err} state_t;
typedef enum {shft, eval, none} action_t;

static state_t stateTable[7][20] = {
{lead, dec, dec, dec, dec, dec, dec, dec, dec, dec, err, err, err,
err, err, err, err, err, start, err},
{oct, oct, oct, oct, oct, oct, oct, oct, err, err, err, err, err,
err, err, err, hex, start, tail, err},
{dec, dec, dec, dec, dec, dec, dec, dec, dec, dec, err, err, err,
err, err, err, err, start, tail, err},
{oct, oct, oct, oct, oct, oct, oct, oct, err, err, err, err, err,
err, err, err, err, start, tail, err},
{hex, hex, hex, hex, hex, hex, hex, hex, hex, hex, hex, hex, hex,
hex, hex, hex, err, start, tail, err},
{err, err, err, err, err, err, err, err, err, err, err, err, err,
err, err, err, err, start, tail, err},
{err, err, err, err, err, err, err, err, err, err, err, err, err,
err, err, err, err, err, err, err}
};

static action_t actionTable[7][20] = {
{none, shft, shft, shft, shft, shft, shft, shft, shft, shft, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, none, none, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, shft, shft, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, none, none, none,
none, none, none, none, none, none, eval, none, none},
{shft, shft, shft, shft, shft, shft, shft, shft, shft, shft, shft,
shft, shft, shft, shft, shft, none, eval, none, none},
{none, none, none, none, none, none, none, none, none, none, none,
none, none, none, none, none, none, eval, none, none},
{none, none, none, none, none, none, none, none, none, none, none,
none, none, none, none, none, none, none, none, none}
};
static int mapchar(int c)
{
switch(c)
{
case '0': return 0; break;
case '1': return 1; break;
case '2': return 2; break;
case '3': return 3; break;
case '4': return 4; break;
case '5': return 5; break;
case '6': return 6; break;
case '7': return 7; break;
case '8': return 8; break;
case '9': return 9; break;
case 'a': case 'A': return 10; break;
case 'b': case 'B': return 11; break;
case 'c': case 'C': return 12; break;
case 'd': case 'D': return 13; break;
case 'e': case 'E': return 14; break;
case 'f': case 'F': return 15; break;
case 'x': case 'X': return 16; break;
case '.': case 0: return 17; break;
case ' ': case '\t': case '\n': return 18; break;
default: return 19;
}
}

unsigned long iptolong(const char *ip)
{
unsigned long ipval=0;
unsigned long octet=0;
int base=10;

state_t state = start;
do
{
action_t action = actionTable[state][mapchar(*ip)];
switch(action)
{
case shft:
octet = octet * base + mapchar(*ip);
break;

case eval:
ipval <<= 8;
ipval += octet;
octet = 0;
break;

default:
break;
}

state = stateTable[state][mapchar(*ip)];
switch(state)
{
case dec: base = 10; break;
case oct: base = 8; break;
case hex: base = 16; break;
}
} while(*ip++);

return ipval;

}

int main(int argc, char **argv)
{
unsigned long ipval;
ipval = iptolong(argv[1]);
printf("long value of \"%s\" is %lu (%x)\n", argv[1], ipval,
ipval);

return 0;
}

Feb 3 '06 #35

P: n/a

"Phil Carmody" wrote:
"John F" writes:
reset^=reset;
Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0


maybe... depends on the optimizer... That way I encourage the optimizer into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000
Or do you just think that more is more?


not always :-) depends on the object...

regards
John F(dot)
Feb 3 '06 #36

P: n/a
On 2006-02-03, John F <sp**@127.0.0.1> wrote:

"Phil Carmody" wrote:
"John F" writes:
reset^=reset;


Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0


maybe... depends on the optimizer... That way I encourage the optimizer into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000


How about just passing -Os [or whatever "optimize for size" option] to
the compiler and letting it make that decision? Your "two 3 byte
instructions" also waste a register, and probably take twice as long to
execute, if not longer
Feb 3 '06 #37

P: n/a

"Jordan Abel" wrote:
On 2006-02-03, John F <sp**@127.0.0.1> wrote:

"Phil Carmody" wrote:
"John F" writes:
reset^=reset;

Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0
maybe... depends on the optimizer... That way I encourage the optimizer
into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000


How about just passing -Os [or whatever "optimize for size" option] to
the compiler and letting it make that decision?


-Os is OW ... it doesn't make the decision to translate =0 with x^x ...
There seems to be slight a difference in the semantics tree ... dunno. Have
to dig into that :-) quite interesting why ... or rather why not.
Your "two 3 byte
instructions" also waste a register, and probably take twice as long to
execute, if not longer


BC3.1 does generate xor cx,cx ... that's simple and fast... it will depent
largely on the instruction set that is used.
I'll ask an OW expert how to get the compiler to use ecx ... since it gets
push/pop-ed ... weird stuff.

regards
John
Feb 3 '06 #38

P: n/a

John Bode wrote:
[snip]
Whitespace embedded within the octet token ("1 27.0.0.1")
will cause the function to return 0.


=sigh=

Actually, that's not true. I was thinking of a slightly different
version of this code that I was working on before settling on this
solution. What you should get back in this case is the value of
whatever octets have been processed up to this point.

Again, no error handling in this version.

Feb 3 '06 #39

P: n/a
On 2006-02-03, John F <sp**@127.0.0.1> wrote:

"Jordan Abel" wrote:
On 2006-02-03, John F <sp**@127.0.0.1> wrote:

"Phil Carmody" wrote:
"John F" writes:
> reset^=reset;

Are you hoping that your compiler will turn that into
xor eax,eax
and thus be faster than
mov eax, 0

maybe... depends on the optimizer... That way I encourage the optimizer
into

mine does generate two 3 byte instructions...
mov eax, dword ptr -0x4[ebp]
xor dword ptr -0x4[ebp],eax

versus one seven byte instruction...
mov dword ptr -0x4[ebp],0x00000000
How about just passing -Os [or whatever "optimize for size" option] to
the compiler and letting it make that decision?


-Os is OW ... it doesn't make the decision to translate =0 with x^x ...
There seems to be slight a difference in the semantics tree ... dunno. Have
to dig into that :-) quite interesting why ... or rather why not.
Your "two 3 byte
instructions" also waste a register, and probably take twice as long to
execute, if not longer


BC3.1 does generate xor cx,cx ... that's simple and fast... it will depent
largely on the instruction set that is used.


The problem is that your variable is in memory, so storing an 0 literal
to it is faster than the "xor trick"
I'll ask an OW expert how to get the compiler to use ecx ... since it gets
push/pop-ed ... weird stuff.


It sounds like you don't really understand asm
Feb 3 '06 #40

P: n/a
John F wrote:
reset^=reset;

"Jordan Abel" wrote: The problem is that your variable is in memory, so storing an 0 literal
to it is faster than the "xor trick"
I know... that's why there is no "best solution" except the compiler does
the optimizing in a certain way. That's why I occationally look at the
disassembly.
I'll ask an OW expert how to get the compiler to use ecx ... since it
gets
push/pop-ed ... weird stuff.

It sounds like you don't really understand asm


I do understand ASM ... x86, C166, 8051, MIPS, some DSPs ... so ...
I just did not get the right switches for forcing reset into a register.
Now I get it (see listing below...) some debug options prevented the
compiler from doing most optimisazion...
It does optimize reset=0; to the same instruction now... so ... excellent
work done by OW ... I knew it did work somehow ;-)

see 002E... that's what I intended to get...

regards
John

Listing (use fixed kerning font):
Segment: _TEXT PARA USE32 000000A4 bytes
0000 iptol_:
0000 53 push ebx
0001 51 push ecx
0002 52 push edx
0003 56 push esi
0004 57 push edi
0005 55 push ebp
0006 89 C5 mov ebp,eax
0008 B9 01 00 00 00 mov ecx,0x00000001
000D 31 F6 xor esi,esi
000F 31 D2 xor edx,edx
0011 80 38 00 cmp byte ptr [eax],0x00
0014 74 06 je L$2
0016 L$1:
0016 40 inc eax
0017 80 38 00 cmp byte ptr [eax],0x00
001A 75 FA jne L$1
001C L$2:
001C 89 C3 mov ebx,eax
001E 89 EF mov edi,ebp
0020 48 dec eax
0021 29 DF sub edi,ebx
0023 74 39 je L$7
0025 80 38 2E cmp byte ptr [eax],0x2e
0028 75 06 jne L$3
002A 48 dec eax
002B C1 E1 08 shl ecx,0x08
002E 31 D2 xor edx,edx
0030 L$3:
0030 83 FA 01 cmp edx,0x00000001
0033 75 16 jne L$5
0035 BB 0A 00 00 00 mov ebx,0x0000000a
003A L$4:
003A 0F BE 38 movsx edi,byte ptr [eax]
003D 83 EF 30 sub edi,0x00000030
0040 0F AF F9 imul edi,ecx
0043 0F AF DF imul ebx,edi
0046 42 inc edx
0047 01 DE add esi,ebx
0049 EB D1 jmp L$2
004B L$5:
004B 83 FA 02 cmp edx,0x00000002
004E 75 07 jne L$6
0050 BB 64 00 00 00 mov ebx,0x00000064
0055 EB E3 jmp L$4
0057 L$6:
0057 BB 01 00 00 00 mov ebx,0x00000001
005C EB DC jmp L$4
005E L$7:
005E 89 F0 mov eax,esi
0060 5D pop ebp
0061 5F pop edi
0062 5E pop esi
0063 5A pop edx
0064 59 pop ecx
0065 5B pop ebx
0066 C3 ret
Feb 3 '06 #41

P: n/a
On 02 Feb 2006 20:56:38, Herbert Kleebauer <kl**@unibwm.de> wrote:
RSoIsCaIrLiIoA wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
>I am trying to write a function to convert an ipv4 address that is held
>in the string char *ip to its long value equivalent. Here is what I
>have right now, but I can't seem to get it to work.


do you like my last try?

Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?


in the origin was

"ping 192.0xb2.031.249"

it is for convert ip number like above; the number can be after each
point hexadecimal, decimal or octotal. you are right, i have not
'reduced' it; you are not the only one that like
small programs :))))))))
Feb 5 '06 #42

P: n/a
On Sun, 05 Feb 2006 15:51:26 +0100, RSoIsCaIrLiIoA <zz@zz.z> wrote:
On 02 Feb 2006 20:56:38, Herbert Kleebauer <kl**@unibwm.de> wrote:
RSoIsCaIrLiIoA wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
>I am trying to write a function to convert an ipv4 address that is held
>in the string char *ip to its long value equivalent. Here is what I
>have right now, but I can't seem to get it to work.

do you like my last try?

Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?


in the origin was

"ping 192.0xb2.031.249"

it is for convert ip number like above; the number can be after each
point hexadecimal, decimal or octotal. you are right, i have not
'reduced' it; you are not the only one that like
small programs :))))))))


i have try to reduce but with no success
yes in this case i'm long: i add some comments
do you like my "spaghetti" code ? :))
how many people can write or read code like that?
(i thik for read only the cpu in .exe and nobody in conventional
assembly form)

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams , _isspace
global _main

section _TEXT public align=1 class=CODE use32
; unsigned otto_to_u(char* dove, char* arr)
; legge numeri che sono considerati di base 8
; di al massimo tre cifre significative
; del tipo 0123 oppure 0 oppure 01 oppure 012
; che hanno il terminatore '.' o '\n' o ' ' o '\t'
; in caso di errore 'dove'='arr'; altrimenti
; 'dove' punta al prossimo carattere non letto
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
otto_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, '7'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1: ; 9=TAB
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, 9
je .a4
cmp edx, 0
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
shl eax, 3
sub edx, '0'
add eax, edx
inc esi
dec ecx
jnz .a0

..a3:
mov dl, [esi]
jmp short .e1
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned decarr_to_u(char* dove, char* arr)
; legge numeri che sono considerati di base 10
; di al massimo tre cifre significative
; [del tipo 123 oppure 1 oppure 12]
; che hanno il terminatore '.' o '\n' o ' ' o '\t'
; in caso di errore 'dove'='arr'; altrimenti
; 'dove' punta al prossimo carattere non letto
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
decarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
..a0:
mov dl, [esi]
..a1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
..e2:
cmp edx, ' '
je .a4
cmp edx, 0
je .a4
cmp edx, 9
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
lea ebx, [4*eax+eax]
sub edx, '0'
lea eax, [2*ebx]
add eax, edx
inc esi
dec ecx
jnz .a0

..a3:
mov dl, [esi]
jmp short .e2
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned hexarr_to_u(char* dove, char* arr)
; legge numeri che sono considerati di base 16
; di al massimo tre cifre significative
; del tipo 0x123 oppure 0x0 oppure 0X1 oppure 0x12
; che hanno il terminatore '.' o '\n' o ' ' '\t'
; in caso di errore dove=arr; altrimenti
; dove punta al prossimo carattere non letto
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
hexarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], 'x'
je .h0
cmp byte[esi], 'X'
je .h0
jmp .e0
..h0:
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, 'F'
ja .c0
cmp edx, 'A'
jb .c0
sub edx, 'A'
add edx, 10
jmp short .a2
..c0:
cmp edx, 'f'
ja .c1
cmp edx, 'a'
jb .c1
sub edx, 'a'
add edx, 10
jmp short .a2
..c1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
sub edx, '0'
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp .fn
..e1:
cmp ecx, 3
je .e0
..e2:
cmp edx, ' '
je .a6
cmp edx, 0
je .a6
cmp edx, 9
je .a6
cmp edx, 10
je .a6
cmp edx, '.'
je .a6
jmp short .e0

..a2:
shl eax, 4
inc esi
add eax, edx
dec ecx
jnz .a0

..a3:
mov dl, [esi]
jmp short .e2
..a6:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret
; ip_to_ul(dword* ris, dword* arr)
; trasforma un numero ip del tipo 0x23.023.123.123
; in un numero di 32 bit. i 4 campi devono essere
; separati *solo* da un punto, devono essere compresi
; tra 0 e 255 non possono avere zeri non significativi.
; I quattro campi possono essere dati come
; numero decimale (es. 125), esadecimale (es. 0x4, 0X9)
; ottottale (es. 012, 01, 0)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; @w
sub esp, 32 ; 21..24 <32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @w ebp+24
mov esi, [@arr]
xor ebx, ebx
jmp short .c1
..c0:
inc esi
..c1:
mov bl, [esi]
cmp ebx, ' '
je .c0
cmp ebx, 9
je .c0

cmp bl, 0
jne .c2
..e0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..c2: ; c=1.2.3.4
mov ecx, 4
mov edx, 0
mov ebx, 0
..c3:
cmp byte[esi], '0'
jne .b0
cmp byte[esi+1], 'x'
je .a1
cmp byte[esi+1], 'X'
jne .a2
..a1:
lea eax, [@w]
push esi
push eax
call hexarr_to_u
add esp, 8
jmp short .c4
..a2:
lea eax, [@w]
push esi
push eax
call otto_to_u
add esp, 8
jmp short .c4
..b0:
lea eax, [@w]
push esi
push eax
call decarr_to_u
add esp, 8
..c4:
cmp esi, [@w]
je .e0
cmp eax, 255
ja .e0
shl ebx, 8
mov esi, [@w]
add ebx, eax
cmp ecx, 1
je .c5
cmp byte[esi], '.'
jne .e0
jmp short .c6
..c5:
cmp byte[esi], ' '
je .c7
cmp byte[esi], 10
je .c7
cmp byte[esi], 9
je .c7
jmp .e0
..c6:
inc esi
dec ecx
jmp .c3
..c7:
mov eax, [@ris]
mov dword[eax], 1
mov eax, ebx
..fn:
%undef @ris
%undef @arr
%undef @w
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret
; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]

push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
Feb 5 '06 #43

P: n/a
On Sun, 05 Feb 2006 20:06:59 +0100, in comp.lang.c , RSoIsCaIrLiIoA
<zz@zz.z> wrote:

(more assembler)

Please stop x-posting assembler to comp.lang.c where it is violently
offtopic.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Feb 5 '06 #44

P: n/a
RSoIsCaIrLiIoA wrote:
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret


*PLONK*

--
BR, Vladimir

If you can't be good, be careful. If you can't be careful, give me a
call.

Feb 5 '06 #45

P: n/a
# in the origin was
#
# "ping 192.0xb2.031.249"

int convert(char *string,unsigned char *address,int length) {
int i; char *p,*q;
for (i=0,p=string; i<length && *p; i++,p=q) {
switch (*p) {
case ':': address[i] = strtol(p,&q,16); break;
case '.': p++;
default:
if (!isdigit(*p)) return -1; /*component not a number*/
address[i] = strtol(p,&q,0);
break;
}
if (p==q) return -2; /* malformed component*/
}
if (*p) return -3; /*string has too many components*/
return i;
}

long ip4pack(unsigned char *address /*length==4*/) {
int i; long a = 0;
for (i=0; i<4; i++) a = (a<<8)|address[i];
return htonl(a);
}

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Wow. A sailboat.
Feb 6 '06 #46

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> écrivait
news:11*************@corp.supernews.com:
Wow. A sailboat.


Yes.

:)

Betov.

< http://rosasm.org >
Feb 6 '06 #47

P: n/a
On 1 Feb 2006 18:08:24 GMT, Chris Torek <no****@torek.net> wrote:
<snip>
#if OFFTOPIC == IP_and_BSD_networking
Traditionally, each octet is allowed to be in decimal, hex, or
octal, independent of each previous octet. To match "traditional
BSD semantics", make the strtoul() call above use base 0.

Yes, this means that you can "ping 192.0xb2.031.249". No, there
is no particularly good reason to do that -- and some implementations
do not allow it (but some spammers do depend on it to hide their
"real" IP addresses).
And if you mistakenly use a fixed format, as one app I worked on did,
extra-0 means octal and e.g. 192.168.010.077 produces results
different from what almost any sane person wants or expects.
(Traditional BSD libraries also allow the entire 32-bit address to
be given as a single number, but that requires more code, whereas
changing the last argument to strtoul() does not.)


Actually tradition allows 1.3 and 1.1.2 as well as 1.1.1.1 and 4.
These were originally intended for class A and B networks back when
(it was thought) addresses were actually going to be assigned that
way. IME spammers and other miscreants more often use these formats,
especially 4, than just hex-ed octets. Although it it used to amuse me
when they forged Received headers with e.g. 123.345.567.789.
("Used to" because nowadays I no longer bother looking.)

- David.Thompson1 at worldnet.att.net
Feb 13 '06 #48

P: n/a

"RSoIsCaIrLiIoA" wrote:
On 02 Feb 2006 20:56:38, Herbert Kleebauer <kl**@unibwm.de> wrote:
RSoIsCaIrLiIoA wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
>I am trying to write a function to convert an ipv4 address that is held
>in the string char *ip to its long value equivalent. Here is what I
>have right now, but I can't seem to get it to work.

do you like my last try?

Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?


in the origin was

"ping 192.0xb2.031.249"

it is for convert ip number like above; the number can be after each
point hexadecimal, decimal or octotal. you are right, i have not
'reduced' it; you are not the only one that like
small programs :))))))))


How about that function, I wrote it some time ago ... know what? it still
works :-)

//doesn't need any library functions, pure C
//@param: IP: NULL-terminated string of the addy
unsigned long iptol(char* IP) {
char* runner=IP;
unsigned long factor=1;
unsigned long temp=0;
unsigned int reset=0;

//roll in to the last char...
while(*runner) runner++;

//seek dots from back to forth
while((IP - runner--)) {
if(*runner=='.') {
factor <<= 8;
reset=0;
runner--;
}
temp += (factor * (*(runner) - '0') *
(reset==1?10:(reset==2?100:1)));
reset++;
}
return temp;
}

It even does convert 10.10.10.10.10.10.10 and so on .... well some
intelligence could still be added.

--
John
Feb 18 '06 #49

P: n/a
On Sun, 05 Feb 2006 15:51:26 +0100, RSoIsCaIrLiIoA <zz@zz.z> wrote:
find this line
************************************************** **************
On 02 Feb 2006 20:56:38, Herbert Kleebauer <kl**@unibwm.de> wrote:
RSoIsCaIrLiIoA wrote:
On 31 Jan 2006 12:27:07 -0800, "kyle.tk" <ky*****@gmail.com> wrote:
>I am trying to write a function to convert an ipv4 address that is held
>in the string char *ip to its long value equivalent. Here is what I
>have right now, but I can't seem to get it to work.

do you like my last try?

Do you want to convert a string like "137.193.64.130" into a 32 bit value
stored in a register (eax)? And for this you need more than 350 line of
code?


in the origin was

"ping 192.0xb2.031.249"

it is for convert ip number like above; the number can be after each
point hexadecimal, decimal or octotal. you are right, i have not
'reduced' it; you are not the only one that like
small programs :))))))))


i have try to reduce but with no success
yes in this case i'm long: i add some comments
do you like my "spaghetti" code ? :))
how many people can write or read code like that?
(i thik for read only the cpu in .exe and nobody in conventional
assembly form)

; nasmw -f obj this_file.asm
; bcc32 this_file.obj

section _DATA public align=4 class=DATA use32

Scrivi_numero_ip db "Srivi un internet adr. > " , 0
Errore db "Errore" , 10 , 0
Errore1 db "Errore" , 0
Errore_linea_troppo_lunga db "Errore linea troppo lunga" , 0
Numero_naturale_conversione_$u
db "Numero naturale conversione %u" , 10 , 0
Errore_contenuto_linea db "Errore contenuto linea" , 10 , 0

$lf db "%lf" , 0
errno_u_$i db "errno=%i " , 0
$u_$u db " <%u %u> " , 0
$i_p$i_p$i_p$i db " %d.%d.%d.%d%*[^" , 10 , "]" , 0
val db 0

extern _printf , _errno , _sscanf , _fgets
extern _perror , __streams , _isspace
global _main

section _TEXT public align=1 class=CODE use32
; unsigned otto_to_u(char* dove, char* arr)
; legge numeri che sono considerati di base 8
; di al massimo tre cifre significative
; del tipo 0123 oppure 0 oppure 01 oppure 012
; che hanno il terminatore '.' o '\n' o ' ' o '\t'
; in caso di errore 'dove'='arr'; altrimenti
; 'dove' punta al prossimo carattere non letto
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
otto_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, '7'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1: ; 9=TAB
cmp edx, ' '
je .a4
cmp edx, 10
je .a4
cmp edx, 9
je .a4
cmp edx, 0
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
shl eax, 3
sub edx, '0'
add eax, edx
inc esi
dec ecx
jnz .a0

..a3:
mov dl, [esi]
jmp short .e1
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned decarr_to_u(char* dove, char* arr)
; legge numeri che sono considerati di base 10
; di al massimo tre cifre significative
; [del tipo 123 oppure 1 oppure 12]
; che hanno il terminatore '.' o '\n' o ' ' o '\t'
; in caso di errore 'dove'='arr'; altrimenti
; 'dove' punta al prossimo carattere non letto
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
decarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
..a0:
mov dl, [esi]
..a1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp short .fn
..e1:
cmp ecx, 3
je .e0
..e2:
cmp edx, ' '
je .a4
cmp edx, 0
je .a4
cmp edx, 9
je .a4
cmp edx, 10
je .a4
cmp edx, '.'
je .a4
jmp short .e0

..a2:
lea ebx, [4*eax+eax]
sub edx, '0'
lea eax, [2*ebx]
add eax, edx
inc esi
dec ecx
jnz .a0

..a3:
mov dl, [esi]
jmp short .e2
..a4:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret

; unsigned hexarr_to_u(char* dove, char* arr)
; legge numeri che sono considerati di base 16
; di al massimo tre cifre significative
; del tipo 0x123 oppure 0x0 oppure 0X1 oppure 0x12
; che hanno il terminatore '.' o '\n' o ' ' '\t'
; in caso di errore dove=arr; altrimenti
; dove punta al prossimo carattere non letto
; s=0c, 4i, 8r, 12b, 16ra, 20dove, 24arr
hexarr_to_u:
push ebx
push edx
push esi
push ecx
mov esi, [esp+24]
mov edx, 0
mov eax, 0
mov ecx, 3
cmp byte[esi], '0'
jne .e0
inc esi
cmp byte[esi], 'x'
je .h0
cmp byte[esi], 'X'
je .h0
jmp .e0
..h0:
inc esi
..a0:
mov dl, [esi]
..a1:
cmp edx, 'F'
ja .c0
cmp edx, 'A'
jb .c0
sub edx, 'A'
add edx, 10
jmp short .a2
..c0:
cmp edx, 'f'
ja .c1
cmp edx, 'a'
jb .c1
sub edx, 'a'
add edx, 10
jmp short .a2
..c1:
cmp edx, '9'
jg .e1
cmp edx, '0'
jl .e1
sub edx, '0'
jmp short .a2
..e0:
mov eax, [esp+24]
mov ebx, [esp+20]
mov [ebx], eax
mov eax, 0
jmp .fn
..e1:
cmp ecx, 3
je .e0
..e2:
cmp edx, ' '
je .a6
cmp edx, 0
je .a6
cmp edx, 9
je .a6
cmp edx, 10
je .a6
cmp edx, '.'
je .a6
jmp short .e0

..a2:
shl eax, 4
inc esi
add eax, edx
dec ecx
jnz .a0

..a3:
mov dl, [esi]
jmp short .e2
..a6:
mov edx, [esp+20]
mov [edx], esi
..fn:
pop ecx
pop esi
pop edx
pop ebx
ret
; ip_to_ul(dword* ris, dword* arr)
; trasforma un numero ip del tipo 0x23.023.123.123
; in un numero di 32 bit. i 4 campi devono essere
; separati *solo* da un punto, devono essere compresi
; tra 0 e 255 non possono avere zeri non significativi.
; I quattro campi possono essere dati come
; numero decimale (es. 125), esadecimale (es. 0x4, 0X9)
; ottottale (es. 012, 01, 0)
; k=0k, 4Ra, 8ris, 12arr
ip_to_ul:
push ebp
mov ebp, esp ; @w
sub esp, 32 ; 21..24 <32
push ebx
push ecx
push edx
push esi
push edi
%define @ris ebp+8
%define @arr ebp+12
%define @w ebp+24
*********************************************
this should be
"%define @w ebp-24 "
*********************************************
mov esi, [@arr]
xor ebx, ebx
jmp short .c1
..c0:
inc esi
..c1:
mov bl, [esi]
cmp ebx, ' '
je .c0
cmp ebx, 9
je .c0

cmp bl, 0
jne .c2
..e0:
mov eax, [@ris]
mov dword[eax], 0
jmp .fn
..c2: ; c=1.2.3.4
mov ecx, 4
mov edx, 0
mov ebx, 0
..c3:
cmp byte[esi], '0'
jne .b0
cmp byte[esi+1], 'x'
je .a1
cmp byte[esi+1], 'X'
jne .a2
..a1:
lea eax, [@w]
push esi
push eax
call hexarr_to_u
add esp, 8
jmp short .c4
..a2:
lea eax, [@w]
push esi
push eax
call otto_to_u
add esp, 8
jmp short .c4
..b0:
lea eax, [@w]
push esi
push eax
call decarr_to_u
add esp, 8
..c4:
cmp esi, [@w]
je .e0
cmp eax, 255
ja .e0
shl ebx, 8
mov esi, [@w]
add ebx, eax
cmp ecx, 1
je .c5
cmp byte[esi], '.'
jne .e0
jmp short .c6
..c5:
cmp byte[esi], ' '
je .c7
cmp byte[esi], 10
je .c7
cmp byte[esi], 9
je .c7
jmp .e0
..c6:
inc esi
dec ecx
jmp .c3
..c7:
mov eax, [@ris]
mov dword[eax], 1
mov eax, ebx
..fn:
%undef @ris
%undef @arr
%undef @w
pop edi
pop esi
pop edx
pop ecx
pop ebx
mov esp, ebp
pop ebp
ret
; k= 0k, 4Ra, 8@argc, 12@argv
_main: ; foo[256], sp[4], w[4]

push ebp ; 11..266, 267..270, 271..274<512
mov ebp, esp
sub esp, 512
push ebx
push esi
push edi
%define @argc ebp+8
%define @argv ebp+12
%define @foo ebp-266
%define @w ebp-274
mov eax, 0
mov ebx, ebp
..l0:
mov byte[ebx], 0
inc eax
dec ebx
cmp eax, 400
jb .l0
..a0:
push Scrivi_numero_ip
call _printf
add esp, 4
lea eax, [@foo]
push __streams
push 256
push eax
call _fgets
add esp, 12
cmp eax, 0
jne .l4
..l1:
push Errore
call _printf
add esp, 4
jmp .fine
..l2:
push Errore_linea_troppo_lunga
call _printf
add esp, 4
jmp .fine
..l3:
push Errore_contenuto_linea
call _printf
add esp, 4
jmp .fine
..l4:
cmp byte[eax+254], 0
jne .l2
lea ebx, [@w]
push eax
push ebx
call ip_to_ul
add esp, 8
cmp dword[@w], 0
je .l3
cmp eax, 0
je .fine
push eax
push Numero_naturale_conversione_$u
call _printf
add esp, 8
jmp .l0
..fine:
mov eax, 0
%undef @argc
%undef @argv
%undef @foo
%undef @w
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
Apr 25 '06 #50

65 Replies

This discussion thread is closed

Replies have been disabled for this discussion.