Bug 847376

Summary: nm_utils_ip4_prefix_to_netmask fails to work with 24
Product: [Fedora] Fedora Reporter: Mark Hamzy <hamzy>
Component: anacondaAssignee: Radek Vykydal <rvykydal>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: urgent Docs Contact:
Priority: urgent    
Version: rawhideCC: anaconda-maint-list, clumens, danw, dcbw, dmalcolm, extras-orphan, g.kaviyarasu, jonathan, notting, vanmeeuwen+fedora
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: ppc64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-09-03 21:49:51 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 846989    
Attachments:
Description Flags
[PATCH] integer out of range for L format code none

Description Mark Hamzy 2012-08-10 19:05:52 UTC
[anaconda root@sharpie /]# cat << __EOF__ | python -
import ctypes
ctypes.cdll.LoadLibrary("libnm-util.so.2")
nm_utils = ctypes.CDLL("libnm-util.so.2")
print nm_utils.nm_utils_ip4_prefix_to_netmask(24)
__EOF__
-256

The expected result should be:
16777215

Comment 1 Dave Malcolm 2012-08-10 19:16:06 UTC
The code is buggy: you need to specify the type of the args and returntype (otherwise they defaults to c "int")


>>> import ctypes
>>> ctypes.cdll.LoadLibrary("libnm-util.so.2")
<CDLL 'libnm-util.so.2', handle 100297b7a70 at 10029749290>
>>> nm_utils = ctypes.CDLL("libnm-util.so.2")
>>> print nm_utils.nm_utils_ip4_prefix_to_netmask(24)
-256

but setting the argtypes and restype:
>>> nm_utils.nm_utils_ip4_prefix_to_netmask.argtypes = [ctypes.c_uint32]
>>> nm_utils.nm_utils_ip4_prefix_to_netmask.restype = ctypes.c_uint32
>>> print nm_utils.nm_utils_ip4_prefix_to_netmask(24)
4294967040

See http://docs.python.org/library/ctypes.html#specifying-the-required-argument-types-function-prototypes
and http://docs.python.org/library/ctypes.html#return-types

Comment 2 Dave Malcolm 2012-08-10 19:18:04 UTC
...basing the types in comment 1 on the prototype here:
http://developer.gnome.org/libnm-util/unstable/libnm-util-nm-utils.html#nm-utils-ip4-prefix-to-netmask

which says:
 guint32   nm_utils_ip4_prefix_to_netmask (guint32 prefix);

Note that ctypes can't check these types; if you get them wrong (or rely on the defaults) you're likely to get the wrong results (or a crash).

Comment 3 Mark Hamzy 2012-08-10 22:43:27 UTC
With the above mentioned fix, there is still a difference between ppc64 and x86_64


[anaconda root@sharpie /]# uname -a
Linux sharpie.rchland.ibm.com 3.3.4-5.fc17.ppc64 #1 SMP Mon May 14 10:18:37 MST 2012 ppc64 ppc64 ppc64 GNU/Linux
[anaconda root@sharpie /]# cat << __EOF__ | python -
import ctypes
ctypes.cdll.LoadLibrary("libnm-util.so.2")
nm_utils = ctypes.CDLL("libnm-util.so.2")
nm_utils.nm_utils_ip4_prefix_to_netmask.argtypes = [ctypes.c_uint32]
nm_utils.nm_utils_ip4_prefix_to_netmask.restype = ctypes.c_uint32
val = nm_utils.nm_utils_ip4_prefix_to_netmask(24)
print val
print hex(val)
__EOF__
4294967040
0xffffff00L


--- versus ---


[root@hamzy-fedora17-build ~]# uname -a
Linux hamzy-fedora17-build.localdomain 3.4.6-2.fc17.x86_64 #1 SMP Thu Jul 19 22:54:16 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
[root@hamzy-fedora17-build ~]# cat << __EOF__ | python -
import ctypes
ctypes.cdll.LoadLibrary("libnm-util.so.2")
nm_utils = ctypes.CDLL("libnm-util.so.2")
nm_utils.nm_utils_ip4_prefix_to_netmask.argtypes = [ctypes.c_uint32]
nm_utils.nm_utils_ip4_prefix_to_netmask.restype = ctypes.c_uint32
val = nm_utils.nm_utils_ip4_prefix_to_netmask(24)
print val
print hex(val)
__EOF__
16777215
0xffffffL

Comment 4 Mark Hamzy 2012-08-13 14:27:24 UTC
8<---8<---
/*
vi bob.c && gcc -o bob `pkg-config --cflags --libs libnm-util` bob.c && ./bob
*/

#include <stdio.h>
#include <nm-utils.h>

int
main (int argc, char *argv[])
{
        guint32 netmask;

        netmask = nm_utils_ip4_prefix_to_netmask (24);

        printf ("nm_utils_ip4_prefix_to_netmask (24) returns %d\n", netmask);

        return 0;
}
8<---8<---

[root@hamzy-fedora17-build ~]# uname -a
Linux hamzy-fedora17-build.localdomain 3.4.6-2.fc17.x86_64 #1 SMP Thu Jul 19 22:54:16 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
[root@hamzy-fedora17-build ~]# vi bob.c && gcc -o bob `pkg-config --cflags --libs libnm-util` bob.c && ./bob
nm_utils_ip4_prefix_to_netmask (24) returns 16777215

[root@bluebill ~]# uname -a
Linux bluebill.rchland.ibm.com 3.3.4-5.fc17.ppc64 #1 SMP Mon May 14 10:18:37 MST 2012 ppc64 ppc64 ppc64 GNU/Linux
[root@bluebill ~]# vi bob.c && gcc -o bob `pkg-config --cflags --libs libnm-util` bob.c && ./bob
nm_utils_ip4_prefix_to_netmask (24) returns -256

Comment 5 Dan Williams 2012-08-13 16:04:36 UTC
The returned value is *unsigned*, and in this case, since the prefix netmask is so large in BE (255.255.255.0, = 42949767040), the high bit will be set, which means treating this as a plain integer will yield a negative number.  And since the lower 8 bits are all 0, treating that as a signed number would match up with -256.

Which means you want a %u there instead of a %d, right?

Comment 6 Dan Williams 2012-08-13 16:06:40 UTC
%u on both my iBook G3 and my x86_64 box gives me 4294967040 (G3) and 16777215 (x86_64).

Also, note that the returned value from nm_utils_ip4_prefix_to_netmask() is network byte order; I've just clarified that in the code documentation too.  It's supposed to be opposite of nm_utils_ip4_netmask_to_prefix() which takes a netmask in network byte order.

Comment 9 Dan Williams 2012-08-14 15:41:46 UTC
So I'll close as "worksforme" for now; if that's not correct, please reopen.  Thanks!

Comment 10 Mark Hamzy 2012-08-14 16:40:27 UTC
Created attachment 604365 [details]
[PATCH] integer out of range for L format code

Comment 11 Mark Hamzy 2012-08-14 16:51:11 UTC
Reopening this as an anaconda bug.

Comment 12 Mark Hamzy 2012-08-14 16:53:12 UTC
Does the call to http://docs.python.org/library/socket.html#socket.inet_ntoa expect network byte order data?

Comment 13 Dave Malcolm 2012-08-14 17:56:39 UTC
(In reply to comment #12)
> Does the call to http://docs.python.org/library/socket.html#socket.inet_ntoa
> expect network byte order data?

Python's socket.inet_ntoa (implemented in Modules/socketmodule.c) is a thin wrapper around glibc's inet_ntoa, and the manpage for that call says:

  "The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation."

Hence I believe the answer is "network byte order".

Comment 14 Chris Lumens 2012-09-01 13:56:14 UTC
You guys aren't still seeing this bug, are you?

Comment 15 Mark Hamzy 2012-09-03 21:49:51 UTC
No.  I was hoping for clarification from Radek that the anaconda code won't have any further issues with network byte order information.  But I can see that this won't happen.  Closing this defect.