Broadcom 570x and 575x, AppleBCM57xx does't have a clue.. |
![]() |
Broadcom 570x and 575x, AppleBCM57xx does't have a clue.. |
|
noahbody99
InsanelyMac Protégé
|
![]() |
Sep 23 2008, 04:08 PM Post #561
|
|
Thanks to Loepere's previous post, I was able to get the Broadcom BCM 5755M (device id 1673) working flawlessly on my Dell Latitude D830 running Leopard 10.5.4 (no more GSOD or "freezing" after limited use).
I used EternalEmpty's AppleBCM5751Ethernet.kext (downloaded BCM57XX.zip from http://forum.insanelymac.com/index.php?sho...114605&st=0). I followed the directions in the tutuorial. I then changed the entry in /System/Library/Extensions/AppleBCM5751Ethernet.kext/Contents/Info.plist: pci14e4,167d to pci14e4,1673 (my device id) Then I copied /System/Library/Extensions/AppleBCM5751Ethernet.kext/Contents/MacOS/AppleBCM5751Ethernet to my home folder so I could edit it with Hexedit, and replaced all occurrences: "66 81 FA 7D 16" with "66 81 FA 73 16" to match my device id. Note: I did not change address 37554, 37555 of "75 71" to "EB 71" to bypass the call to InitNVRam - I left it as it should be ("75 71"). And now here is the elusive solution... I located the section BCM5751Enet::getAdapterInfo and found the identical code which Loepere refers to. I changed "jne L1" into a "je L1" which using Hexedit simply translates to: address 376C0: replace "F8 08 75 59" with "F8 08 74 59" Copied the modified AppleBCM5751Ethernet back to the original location in /System/Library/Extensions/AppleBCM5751Ethernet.kext/Contents/MacOS. MAC address gets assigned correctly to en0, and DHCP works perfectly. |
|
thestevo
InsanelyMac Chuck Norris
|
![]() |
Sep 23 2008, 06:24 PM Post #562
|
![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
Hello Noahbody99,
I will try your instructions shortly, just to double check the process. However, could you please post your kext? Newer users won't understand this process or wish to follow the instructions. Since you were the first to get it running, you should get the credit for the kext instead of somebody else posting the kext for an average user. theStevo |
|
thefly
InsanelyMac Protégé
|
![]() |
Sep 23 2008, 08:28 PM Post #563
|
|
Could somebody patch this to work with the broadcom BCM5787? This would be great!
|
|
noahbody99
InsanelyMac Protégé
|
![]() |
Sep 23 2008, 09:27 PM Post #564
|
|
OK,
I've attached my modified kext file. It may work for BCM5787 (device id 1693), because I made additional modifications to try to make it work as well, but I can't promise anything since I only have a BCM5755M (device id 1673) and I know it is already working perfectly with that. Noah
Attached File(s)
|
|
thestevo
InsanelyMac Chuck Norris
|
![]() |
Sep 23 2008, 09:44 PM Post #565
|
![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
Noahbody99,
I officially love you! Not only did you provide a method for getting the NIC working, but you saved me a reinstall. I tried your procedure as per your directions and it didn't work. It recognized the adapter, loaded correct MAC, knew cable connection status, but wouldn't do DHCP right or transfer IP even with manual settings. I was going to reinstall because I was sure that the VMware or Parallels network kexts were somehow messing with it, but now I don't need to. I must have missed something, so it may be helpful if you could carefully check your procedure above. However, your kext seems to work fine! Now, a quick question. How did you know where "jne L1" was and what to change it to? Hex Edit and HexFiend didn't show jne L1 in ASCI, so I'm wondering how you knew where it was. Plus, I understand the concept of what changing jne L1 did, but how did you know to change it to "je L1" instead of "jmp L2" like Loepere mentioned? Thanks again! theStevo |
|
robydream
InsanelyMac Protégé
|
![]() |
Sep 23 2008, 11:05 PM Post #566
|
|
Hy....i have a BCM5787 (device id1693) ant tryed your kext but it does not work...in console is writing....
InitNVRam..magic constant not found..and LAN card is not found... Then i found in order the BCM5787 to be recognized is to be set address 37554, 37555 of "75 71" to "EB 71" (This change causes the call to InitNVRam to be bypassed, which is why the MAC address does not get picked up)... When i have changed it to "75 71" The Card could not be recognized end error,when set to "EB 71" card is recignized, but without MAC and Device and Manufacturer name is Unknown.... (Your kext has set it to "EB 70" so is not recognized) I have the replaced address 376C0: replace "F8 08 75 59" with "F8 08 74 59" and is the same...no MAC but DHCP work great! I have modify kext with "75 71" to bypass InitNVRam and recognize BCM5787, and replace "F8 08 75 59" with "F8 08 74 59"... this last step is for not freezing card..i have tested it and no problem at all... So please...download modified kext and post your comment if is freezing or not... Many thanks people for patching informations...
Attached File(s)
|
|
thefly
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 05:34 AM Post #567
|
|
Hi noahbody99,
Thnx for the patch I will report back here if you are a lifesaver Anyway thnx for the fast replay Greatz The Fly |
|
sandr
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 06:26 AM Post #568
|
![]()
|
Hi all
anybody try this solution to BCM5750 (DEV_16fd) ? |
|
sandr
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 07:16 AM Post #569
|
![]()
|
I located the section BCM5751Enet::getAdapterInfo and found the identical code which Loepere refers to. I changed "jne L1" into a "je L1" which using Hexedit simply translates to: address 376C0: replace "F8 08 75 59" with "F8 08 74 59" Please answer, where located section BCM5751Enet::getAdapterInfo ????? its in file (what file), in log, in osx, in win etc.... |
|
haimon
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 07:58 AM Post #570
|
|
OK, I've attached my modified kext file. It may work for BCM5787 (device id 1693), because I made additional modifications to try to make it work as well, but I can't promise anything since I only have a BCM5755M (device id 1673) and I know it is already working perfectly with that. Noah Hi Noah and everbody Do you help for my? My card is Broadcom 5755, but i can`t made correct kext. Card ID: 167b You can make and upload a kext? Thanks |
|
proosje
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 09:22 AM Post #571
|
|
....So please...download modified kext and post your comment if is freezing or not... Many thanks people for patching informations... I tried your kext RobyDream and i can report that it works for me. MAC address is still all zeros but networking works, and does not seem to freeze. It does freeze if i try to do a ifconfig en0 ether 00:1C:xx:xx:xx:xx My card is a 5787M (id 1693) Thanks |
|
macintrash
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 10:15 AM Post #572
|
![]()
|
OK, I've attached my modified kext file. It may work for BCM5787 (device id 1693), because I made additional modifications to try to make it work as well, but I can't promise anything since I only have a BCM5755M (device id 1673) and I know it is already working perfectly with that. Noah The 5755 and 5787 are quite similar (almost identical, compared to say - a 5786). Linux: http://fxr.watson.org/fxr/ident?v=linux-2....i=ASIC_REV_5755 FreeBSD: http://fxr.watson.org/fxr/source/dev/bge/if_bge.c#L2623 FreeBSD seems to handle it a little differently, to my glance over the hex of the Apple driver, it looks more like a hardcoded choice (like the Linux driver). Could just be that the FreeBSD driver isn't complete (it has some binary code). I think it's enough to work out which jump does what though. I would decompile it, but I don't know how to put it back together again. (Always been better at pulling things apart). Can anyone supply the complete dissasembly in a format that can be recompiled with XCode? I can disassemble with IDA under Windows, but I can't "put humpty dumpty together again." Looking at the Linux code, it shouldn't be too hard to figure out. I'd like to do a proper job though - identify all the check, and which cards need which jumps... or at least have the jumps documented. Here's something I picked up on Google, it's in Spanish, but looks neat. QUOTE Pese a que teníamos un driver funcional, no podíamos parar de darle vueltas al asunto, además el driver que teníamos tenía un problema que queríamos solucionar: se colgaba si intentabas cambiar la MAC con ifconfig, solamente funcionaba al iniciarse el driver. Total que seguimos navegando por el código del driver, hasta que paramos con lo siguiente:
__text:00000000 BCM5751Enet::BCM5751Enet(OSMetaClass const*) proc near __text:00000000 ; CODE XREF: BCM5751Enet::BCM5751Enet(OSMetaClass const*)+14 __text:00000000 ; __text:0000003Cp … __text:00000000 __text:00000000 var_18 = dword ptr -18h __text:00000000 var_14 = dword ptr -14h __text:00000000 arg_0 = dword ptr 8 __text:00000000 arg_4 = dword ptr 0Ch __text:00000000 __text:00000000 000 push ebp __text:00000001 004 mov ebp, esp __text:00000003 004 push ebx __text:00000004 008 sub esp, 14h __text:00000007 01C mov ebx, [ebp+arg_0] __text:0000000A 01C mov eax, [ebp+arg_4] __text:0000000D 01C mov [esp+18h+var_14], eax __text:00000011 01C mov [esp+18h+var_18], ebx __text:00000014 01C call BCM5751Enet::BCM5751Enet(OSMetaClass const*) __text:00000019 01C mov dword ptr [ebx], 0F100h __text:0000001F 01C mov eax, ebx __text:00000021 __text:00000021 loc_21: ; DATA XREF: __data:_mediumTableo __text:00000021 01C add esp, 14h __text:00000024 008 pop ebx __text:00000025 004 pop ebp __text:00000026 000 retn __text:00000026 BCM5751Enet::BCM5751Enet(OSMetaClass const*) endp Dicha función se llamaba varias veces en el driver, y es EXCESIVAMENTE recursiva, tanto que debería cascar el programa, porque la pila a dia de hoy no es infinita, nuestros dialogos en ese momento eran tal que los siguientes: - "como ^!###! puede ser?" - "es imposible que eso se ejecute" - "pero no ves las cantidad de xrefs que tiene!!?" - "que no puede ser" - "mete una int 3 ahí i reinicia" Ni falta hace decir que salto la int 3, con un msg que nos decía que estabamos listos para atachearnos al debugger y nosotros pensando "sí, si tuvieramos debugger aquí ibamos a estar", aunque por otro lado pensamos "oie pues igual eso de tener un debugger no está tan mal", pero claro la depuracion por red del driver de red… como que no, cable serie no teníamos, instalar en una vmware no nos valía porque el hardware es diferente, y la principal razón: no teníamos ni idea de como iba lo de depurar un driver ahí, así que tuvimos que seguir con nuestras int 3´s y nuestros casques … De repente se nos ocurrió una feliz idea: - "oye esto no tendrá relocs?" - "supongo.." - "y que pasa si llenas un buffer de nops y resulta que hay una reloc para algo que hay por el medio" - "oxtia, pues que a saber lo que se ejecuta! xD" - "y la función recursiva esa que hemos visto antes,,, no será que por lo que sea están aplicandose relocs sobre el call …" - "pero ese call es relativo, no _debería_ necesitar relocs!" Y efectivamente … el IDA no interpreta las relocs en los ficheros mach-o todavía, de hecho lo avisa al cargar el ejecutable, pero se ve que no nos sirvió de advertencia … Buscando herramientas de desensamblado, solo por quitarme la curiosidad, vi que con junto con xcode, viene una utilidad llamada otool, que sí que interpreta las relocs, y con la cual obtuve el siguiente desensamblado: __ZN11BCM5751EnetC2EPK11OSMetaClass: 00000000 pushl %ebp 00000001 movl %esp,%ebp 00000003 pushl %ebx 00000004 subl $0×14,%esp 00000007 movl 0×08(%ebp),%ebx 0000000a movl 0×0c(%ebp),%eax 0000000d movl %eax,0×04(%esp,1) 00000011 movl %ebx,(%esp,1) 00000014 calll __ZN20IOEthernetControllerC2EPK11OSMetaClass 00000019 movl $__ZTV11BCM5751Enet,(%ebx) 0000001f movl %ebx,%eax 00000021 addl $0×14,%esp 00000024 popl %ebx 00000025 popl %ebp 00000026 ret Perfecto, nuestra teoría era válida!, ya podíamos hacer parches!, solamente teníamos que tener cuidado de no tocar cosas que pudieran contener codigo que necesitara relocs! ( recordad esto toda vuestra vida!, yo ya lo he apuntado por las paredes de casa, "ojo, relocs!" xD ), así que continuamos con la desgracia del driver… El siguiente paso fue mirar la documentacion de apple del kernel, a ver como se implementaban los drivers ethernet, en el enlace anterior podeís ver que los controladores de este tipo heredan de una clase y deben implementar los metodos que ahí se listan, si bien algunos de ellos, no son obligatorios como es el caso de setHardwareAddress: setHardwareAddress(const IOEthernetAddress *) Sets or changes the station address used by the Ethernet controller. public virtual <a target="_top" class="type" href="http://developer.apple.com/documentation/Darwin/Reference/KernelIOKitFramework/IOReturn/CompositePage.html#//apple_ref/c/tdef/IOReturn">IOReturn setHardwareAddress( const IOEthernetAddress *addrP); <h5 class="tight">Parameters</h5> addrPPointer to an IOEthernetAddress containing the new station address. <h5 class="tight">Return Value</h5> The default implementation will always return kIOReturnUnsupported. If overridden, drivers must return kIOReturnSuccess on success, or an error return code otherwise. <h5 class="tight">Discussion</h5> This method is called in response to a client command to change the station address used by the Ethernet controller. Implementation of this method is optional. This method is called from the workloop context. La implementacion de setHardwareAddress era la siguiente: __text:000012E2 BCM5751Enet::setHardwareAddress(IOEthernetAddress const*): __text:000012E2 push ebp __text:000012E3 mov ebp, esp __text:000012E5 push ebx __text:000012E6 sub esp, 14h __text:000012E9 mov ebx, [ebp+8] ; Interfaz __text:000012EC mov edx, [ebp+0Ch] ; IOEthernetAddress * __text:000012EF test edx, edx ; NULL ? __text:000012F1 jnz short SetMac ; MAC size __text:000012F3 mov eax, 0E00002C2h ; Error code __text:000012F8 jmp short GoOut __text:000012FA ; ————————————————————————— __text:000012FA __text:000012FA SetMac: ; CODE XREF: __text:000012F1j __text:000012FA mov dword ptr [esp+8], 6 ; MAC size __text:00001302 lea eax, [ebx+31Eh] __text:00001308 mov [esp+4], eax ; Mac Offset in the Object __text:0000130C mov [esp], edx ; new IOEthernetAddress * __text:0000130F call BCM5751Enet::BCM5751Enet(OSMetaClass const*) ; Set MAC __text:00001314 mov byte ptr [ebx+367h], 1 __text:0000131B cmp byte ptr [ebx+304h], 0 __text:00001322 jz short SetOptionFailed __text:00001324 mov [esp], ebx __text:00001327 call BCM5751Enet::putToSleep(void) ; Go to dream … __text:0000132C mov [esp], ebx __text:0000132F call BCM5751Enet::getAdapterInfo(void) __text:00001334 mov [esp], ebx __text:00001337 call BCM5751Enet::wakeUp(void) ; Update Object and wake up! __text:0000133C __text:0000133C SetOptionFailed: ; CODE XREF: __text:00001322j __text:0000133C xor eax, eax __text:0000133E __text:0000133E GoOut: ; CODE XREF: __text:000012F8j __text:0000133E add esp, 14h __text:00001341 pop ebx __text:00001342 pop ebp __text:00001343 retn Despues de aplicar un par de parches, nos dimos cuenta de que la tarjeta se quedaba frita al hacer el wakeup y pensamos ¿será necesario hacerlo?, eché un vistazo al driver de la tigon 3 que hay para linux y no parecía que "reseteara" el adaptador en ningun momento, supusimos que la mac se almacenaba en algún registro de la tarjeta, y encontramos que había una funcion que esta anterior llamaba internamente: SetMacAddress(IOEthernetAddress *) , esta accedía a los registros de la tarjeta usando la siguiente función: __text:00001896 BCM5751Enet::write570XRegister(unsigned long volatile*, unsigned long) proc near __text:00001896 ; CODE XREF: __text:000029A6p __text:00001896 ; __text:00002ADFp … __text:00001896 __text:00001896 var_28 = dword ptr -28h __text:00001896 var_24 = dword ptr -24h __text:00001896 var_20 = dword ptr -20h __text:00001896 var_1C = dword ptr -1Ch __text:00001896 var_18 = dword ptr -18h __text:00001896 arg_0 = dword ptr 8 __text:00001896 arg_4 = dword ptr 0Ch __text:00001896 arg_8 = dword ptr 10h __text:00001896 __text:00001896 push ebp __text:00001897 mov ebp, esp __text:00001899 sub esp, 28h __text:0000189C mov edx, [ebp+arg_0] __text:0000189F mov ecx, [ebp+arg_4] __text:000018A2 mov eax, [ebp+arg_8] __text:000018A5 cmp byte ptr [edx+0E1Ch], 0 __text:000018AC jnz short ChangeEndian __text:000018AE mov [esp+28h+var_18], offset aWrite570xregis ; "write570XRegister - write without power"… __text:000018B6 mov [esp+28h+var_1C], 0 __text:000018BE mov [esp+28h+var_20], eax __text:000018C2 mov [esp+28h+var_24], ecx __text:000018C6 mov [esp+28h+var_28], 1 __text:000018CD call BCM5751Enet::KIOLog(uchar,ulong,ulong,ulong,char *) __text:000018D2 jmp short GoOut __text:000018D4 ; ————————————————————————— __text:000018D4 __text:000018D4 ChangeEndian: ; CODE XREF: BCM5751Enet::write570XRegister(ulong volatile*,ulong)+16j __text:000018D4 cmp byte ptr [edx+0E10h], 2 __text:000018DB jnz short DMAWrite __text:000018DD bswap eax __text:000018DF __text:000018DF DMAWrite: ; CODE XREF: BCM5751Enet::write570XRegister(ulong volatile*,ulong)+45j __text:000018DF mov [ecx], eax __text:000018E1 __text:000018E1 GoOut: ; CODE XREF: BCM5751Enet::write570XRegister(ulong volatile*,ulong)+3Cj __text:000018E1 leave __text:000018E2 retn __text:000018E2 BCM5751Enet::write570XRegister(unsigned long volatile*, unsigned long) endp La escritura parecía hacerse en plan acceso directo a memoria, y el msg de "write without power" era mosqueante, al final acabamos pensando que podíamos hacer una prueba: reescribir la implementacion de setHardwareAddress, quitar el wakeup y demás y llamar directamente a SetMacAddress, aplicando también un parchecillo en la funcion de escritura del registro por si acaso no le daba la gana escribir… escribiendo asm en el notepad y parcheando de nuevo con el hiew, quedó una cosa tal que la siguiente: newsetHardwareAddress: mov ebx, [esp+8] ; Iface mov esi, [esp+0c]; IOEthernet jnz Write mov eax, 0E00002C2h jmp Return Write: push esi push ebx call SetMacAddress pop ebx pop esi lea edi [ebx+31Eh] mov ecx, 6 rep movsb xor eax, eax Return : ret Cargamos el driver, intentamos cambiar la MAC y el adaptador no se quedó frito (esto ya pasaba solo quitando el wakeup), la mac en la salida de ifconfig salia cambiada :-), pero no había red, si capturabas tráfico se veía que las peticiones ARP que enviaba la tarjeta llevaban de direccion de origen la nueva, pero se ve que en algun punto el driver no hacía caso a esa nueva configuración de la tarjeta, no llegaba trafico, suponemos que porque el driver pensaba que no era para él, o quizá la propia tarjeta … no ibamos a ponernos a depurar el hardware … así que tuvimos que mandar el driver a paseo, a fin de cuentas ya podíamos utilizarlo en la misma red … de cualquier modo, si alguien sabe la solución o en dónde nos hemos equivocado, me encantaría que me enviara un mail y me comentara o q |
|
EternalEmpty
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 12:23 PM Post #573
|
![]()
|
Thanks to Loepere's previous post, I was able to get the Broadcom BCM 5755M (device id 1673) working flawlessly on my Dell Latitude D830 running Leopard 10.5.4 (no more GSOD or "freezing" after limited use). I used EternalEmpty's AppleBCM5751Ethernet.kext (downloaded BCM57XX.zip from http://forum.insanelymac.com/index.php?sho...114605&st=0). I followed the directions in the tutuorial. I then changed the entry in /System/Library/Extensions/AppleBCM5751Ethernet.kext/Contents/Info.plist: pci14e4,167d to pci14e4,1673 (my device id) Then I copied /System/Library/Extensions/AppleBCM5751Ethernet.kext/Contents/MacOS/AppleBCM5751Ethernet to my home folder so I could edit it with Hexedit, and replaced all occurrences: "66 81 FA 7D 16" with "66 81 FA 73 16" to match my device id. Note: I did not change address 37554, 37555 of "75 71" to "EB 71" to bypass the call to InitNVRam - I left it as it should be ("75 71"). And now here is the elusive solution... I located the section BCM5751Enet::getAdapterInfo and found the identical code which Loepere refers to. I changed "jne L1" into a "je L1" which using Hexedit simply translates to: address 376C0: replace "F8 08 75 59" with "F8 08 74 59" Copied the modified AppleBCM5751Ethernet back to the original location in /System/Library/Extensions/AppleBCM5751Ethernet.kext/Contents/MacOS. MAC address gets assigned correctly to en0, and DHCP works perfectly. pretty good work ..^^ now 1693 is the headache part, I don't have the hardware ..almost can't do anything about it . |
|
nobb1x
InsanelyMac Geek
|
![]() |
Sep 24 2008, 12:41 PM Post #574
|
![]() ![]() ![]()
|
pretty good work ..^^ now 1693 is the headache part, I don't have the hardware ..almost can't do anything about it . a specific kext for 14e4:1693 device is in final testing phase and will be published soon, i hope it will work for anybody with a 5787M (on mine and on other hacks it works) thanks to Loepere, he is the man! OUT NOW http://forum.insanelymac.com/index.php?showtopic=127903 |
|
sandr
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 12:48 PM Post #575
|
![]()
|
how about 14e4:16fd ???
or let me know - where located section BCM5751Enet::getAdapterInfo ?? |
|
super37
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 03:05 PM Post #576
|
|
OK, I've attached my modified kext file. It may work for BCM5787 (device id 1693), because I made additional modifications to try to make it work as well, but I can't promise anything since I only have a BCM5755M (device id 1673) and I know it is already working perfectly with that. Noah cool!!! it works! I love you so much! |
|
sandr
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 04:42 PM Post #577
|
![]()
|
COOOOOl YES ole oleoleole Russia VPERED
Broadcom NetXtreme Lan (VEN_14E4&DEV_16FD) worked with kext modified by this solution im go to testing Many thanks to all |
|
geopingo2008
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 08:02 PM Post #578
|
|
Thanks Noahbody, robydream et al. for the perfect work.
On my Lenovo ThinkPad r61i the modified Broadcom Netlink Gigabit BCM5787 patched kext works absolutely fine. Previous patches only allowed network traffic for a few minutes. Now, the LAN connection holds stable across all speeds (10/100/1000 mbps). Thanks again for the hard work and the numerous hours of testing. But, I guess, in the end it was worth it. ======== Lenovo ThinkPad r61i 2 Gb RAM Iatkos 4i OSX 10.5.4 |
|
haimon
InsanelyMac Protégé
|
![]() |
Sep 24 2008, 10:17 PM Post #579
|
|
Hi Noah and everbody Do you help for my? My card is Broadcom 5755, but i can`t made correct kext. Card ID: 167b You can make and upload a kext? Thanks Hi All I install kalyway 10.5.2, network card don`t work. i install broadcom and IONetworking(kext) from JaS 10.5.4 (patch`s folder in DVD/system/....... String include in AppleBCM5751Ethernet.kext. System profile show 5755 (en0), and show thw real MAC address. I set DHCP first and i set manual IP secund, but both don`t work. any good idea? |
|
macEEL
InsanelyMac Protégé
|
![]() |
Sep 25 2008, 03:16 PM Post #580
|
|
My gx620 started to get internet automatically with the 10.5.5 update, no more need to set up the MAC ADDRESS script.
=) |
![]() |
|
Lo-Fi Version | Time is now: 21st November 2009 - 12:11 PM |