Archive for the ‘Development’ Category
implementing bittorrent (teil 2)
Was macht ein BitTorrent-Tracker? In diesem Teil gehe ich auf die Funktion eines BitTorrent-Trackers ein. Zuerst sollte man sich den Grundsätzlichen Ablauf eines Torrent Downloads anschauen.
1. Download der .torrent-Datei
Der User sucht sich aus seiner Lieblings-Torrent-Quelle (zb TPB, Demonoid, dnbtracker.org ) einen den gewünschten Torrent heraus und lädt ihn auf Seine Festplatte oder öffnet ihn gleich mit seinem BitTorrent-Client.
2. Der Client parst die .torrent-Datei
Für die Kommunikation mit dem Tracker sind nur ein Paar Informationen aus der Metafile interessant (Metafile Infos im ersten Teil)
- der info hash
- die announce urls
3. Der Client kontaktiert den Tracker und sendet ihm den SHA Hash
Die Tracker-Kommunikation läuft über HTTP.
Der Client Schickt einen GET-Request an den Tracker.
Dieser Request besteht aus:
- announce url
- info hash – der SHA1 Hash des Info Dictionaries
- peer id
- port
- uploaded
- downloaded
- left
- compact
- event
Optional aber auch interessant ist:
- key (damit der Tracker einen Client auch nach einem reconnect mit neuer IP wiedererkennt)
Ein Request an einen Tracker könnte dann wie folgt aussehen ( der Tracker laeuft auf example.com):
- http://example.com/announceUrl+”?info_hash=”+urlencode(info)+”&peer_id=-ST-0001%29%7B%D6%40%F4%21%7B%5C%DA%05%DE&port=6881&uploaded=0&downloaded=0&left=0&compact=1&event=started”
Der Tracker erfährt damit von uns folgende Informationen:
- den Hash von der Info-Map (info_hash)
- nsere Peer-ID (peer_id) [zur ID bald mehr]
- den Port auf dem unser Client lauscht (port)
- wir haben noch 0 Pieces hochgeladen (uploaded=0)
- wir haben 0 Pieces heruntergeladen (downloaded=0)
- wir möchten eine Peer-Liste im Kompakten Format (compact=1), das ist auch üblich so. Das alte Format wird praktisch kaum noch genutzt.
- mit dem Event (event=started) teilen wir dem Tracker mit das wir gerade erst mit dem Download beginnen.
4. Tracker Antwort
Der Tracker antwortet mit einer Liste von Peers. Aus dieser Liste kann der Client entnehmen welche Peers die File besitzen. Ob Sie die ganze File besitzen oder nur Fragmente (aus dieser Information wird die obligatorische anzeige der Seeder [complete] bzw Peers [incomplete] realisiert).
Zu den Einzelnen Peers sind die Informationen die dieses bei ihrem Request an den Tracker übertragen haben enthalten, also:
- peer_id
- port
- ip
Zusätzlich teilt einem der Tracker den Intervall mit in dem man diese Informationen auffrischen sollte, bzw einen erneuten Request an den Tracker schicken sollte. Clients sollten sich daran halten um ein hämmern bzw Sinnlosen Overhead zu unterbinden.
Das war es für diesen Teil im großen und ganzen. Ein kleiner überblick auf die Tracker Kommunikation.
Ganz Informativ zu diesem Thema ist auch der Vortrag “Tracker fahrn” (@24C3 – download via http://chaosradio.ccc.de/24c3_m4v_2355.html) von Erdgeist, Denis und Cristian Yxen.
Im nächsten Teil wird es um die Kommunikation unter den Peers gehen.
Tagged: bittorrent, Development, p2p
implementing bittorrent
Mal wieder was technisches. Ich geh mal ein bisschen ins Detail des BitTorrent Protokolls.
Ich werde das ganze in mehrere Teile aufteilen.
In den ersten Teilen wird es sehr Theoretisch.
In Teil 1 möchte ich auf das BEncoding eingehen und auf Metafile die euch sicherlich als “.torrent”-Datei bekannt ist.
Im nächstem Teil gehe ich dann auf grundsätzliches zur Aufgabe eines Trackers ein. Und danach wird es richtig interessant ![]()
Aber erstmal zum BEncoding und der Metafile, ohne die BitTorrent nicht funktioniert -
das BEncoding und die Metafile sind Essentiell!
Bevor ich auf das BEncoding eingehe spreche ich erstmal die MetaFile an, da dies die erste
Stelle (und auch wichtigste) ist an der das BEncoding im Protokoll vorgesehen ist.
Metafile
Die Metafile oder wie es die meisten von euch kennen die “.torrent”-Datei.
In ihr sind alle Informationen (und auch ein paar unwichtige
) die ein Client/Peer benötigt
gespeichert.
Also gehen wir mal näher auf den Inhalt der “.torrent”-Datei ein (optionale Teile sind mit *
gekennzeichnet):
- announce: Die Announce-URL des Trackers
- creation date*: Erstellungsdatum
- comment*: Platz für einen Kommentar zum Torrent oder andere Informationen
- created by*: der Name des Erstellers
- info: das info-Dictionary – der “kern” einer Metafile!(darauf gehe ich weiter unten ein)
Jetzt werden sich sicher einige denken “whuuut?! wtf? dictionary?!”
Ein Dictionary ist die Abbildunge einer Map, oder eines Arrays mit Schlüssel als Index
(ArrayList in Java) auf einen String (bzw. eine ByteFolge xD).
Das Info-Dictionary
Diese Keys enthält ein “info” Dictionary:
- piece length: Die Anzahl der Bytes pro Piece (BitTorrent-Peers tauschen die Daten in Pieces)
- pieces: Enthält die Hashes der Pieces
- info**: Das info-Dictionary für die Spezifizierung der im Torrent enthaltenen Datei/en. (wenn dieses info-Dictionary gemeint ist werde ich es mit ** markieren)
Es gibt 2 verschiedene Modi des Info-Dictionary** den Single-File und den Multifile-Mode,
dementsprechend gibt es auch
2 verschiedene Arten die Datei bzw. die Dateien näher zu Spezifizieren:
“info” im Single-File Mode
- name: Der Dateiname
- length: Länge der Datei in Bytes
“info” im Multi-File Mode
- name: Der Ordnername in dem sich die Dateien befinden
- files: Ein Dictionary das für jede Datei ein weiteres Dictionary enthält
Die Keys des “files”-Dictionaries:
- length: Die grösse der Datei in Bytes
- path: Der Pfad der Datei
Damit waren die wichtigsten Elemente des .torrent-Files erklärt und wir können uns mit de
Kodierung der entsprechenden Elemente/Einträge befassen – dem BEncoding.
BEncoding
Das BEncoding ist so genial wie einfach.
BitTorrent nutzt BEncoding für:
- Strings
- Integer
- Dictionaries
- Listen
Diese Typen werden alle nach dem selben Schema kodiert:
Strings:
: Beispiel: 5:w00t! (für den String "w00t!")
Integer:
ie Beispiel: i7e (Integer: "7") i-1e (Integer: "-1")
Dictionaries:
de Beispiel: d3:nks6:gentoo4:apoc4:arche*** *** Steht für folgendes dictionary: KEY VALUE [nks] = gentoo [apoc] = arch
Listen:
le Beispiel: l3:nks7:torrente (entspricht den Strings "nks" und "torrent")
Ist recht simpel oder?
Trotzdem muss man bei der Implementierung aufpassen, wenn hier ein Fehler passiert kann es sein
das man manchmal hinterher lange nach dem Fehler suchen muss ![]()
Das BEncoding verfolgt einen durch das ganze Protokoll hinweg.
Tagged: bittorrent, Development, java, Networking, p2p, Torrent
kernel mode sockets part 2 (the clean way)
Version 0.3 - 23.01.2009
Willkommen zu teil 2 der linux kernel mode socket Serie. Nun befassen wir uns mit einem sauberem weg der socketcalls vom kernel aus. Auch hierfür gibt es noch andere Wege. In einem der nächsten Teile bauen wir uns eine socket()-Funktion selber, aber nun zum sauberem socket
Auch hier müssen wir wieder set_fs/get_fs (man kann sie auch weglassen, aber in diesem Fall garantiere ich für NICHTS, bzw das Modul lässt sich kompilieren aber die Funktion funktioniert im besten Fall nicht…) nutzen da file-Operationen im kernelmode nicht gestattet sind, der Zugriff auf sockets ist ein Dateizugriff. Die Funktion inet_addr müssen wir uns nicht extra schreiben, hab ich zwischenzeitlich herausgefunden in der “linux/inet.h” gibt es in_aton()
Die Hauptschwierigkeit besteht in den neuen Strukturen iovec und msghdr. Die ich allerdings anhand von Kommentaren erklären werde, soweit wichtig, bzw unter den beiden links steht alles was man wissen muss (obwohl es nicht spezifisch um die linux Strukturen geht).
Ab an den Code:
/* * lkm_clean_socket.c - nks */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/socket.h> #include <linux/net.h> #include <linux/in.h> #include <linux/inet.h> #include <net/sock.h> #include <asm/uaccess.h> int init_module(void) { struct socket *socket; struct sockaddr_in saddr; int errno; char buffer[1024]; struct msghdr msg; struct iovec iov; mm_segment_t old_fs; printk(KERN_INFO "#sixserv/sixserv.org presents:\n"); printk(KERN_INFO "simple & clean kernel mode socket - nks\n"); if ((errno = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&socket))<0) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is up ...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); } saddr.sin_addr.s_addr = in_aton("79.140.33.153"); saddr.sin_port = htons(80); saddr.sin_family = AF_INET; if ((errno = socket->ops->connect(socket,(struct sockaddr*)&saddr,sizeof(saddr),0))<0) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is up an connected...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); } iov.iov_base = "GET / HTTP/1.0\r\n\r\n"; iov.iov_len = sizeof("GET / HTTP/1.0\r\n\r\n"); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_flags = 0; old_fs = get_fs(); set_fs(KERNEL_DS); if ((errno = sock_sendmsg(socket,&msg,sizeof("GET / HTTP/1.0\r\n\r\n")))<0) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is sending stuff...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); set_fs(old_fs); } iov.iov_base = buffer; iov.iov_len = 1024; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_name = NULL; msg.msg_namelen = 0; old_fs = get_fs(); set_fs(KERNEL_DS); if ((errno = sock_recvmsg(socket,&msg,1024,0))<0) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is recieving stuff...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); printk(KERN_INFO "++ Recieved: %s..\n",buffer); set_fs(old_fs); } return 0; } void cleanup_module(void) { printk(KERN_INFO "Goodbye world.\n"); } MODULE_LICENSE("GPL");
Ein weiteres mal passen wir unsere Makfeile an:
obj-m += lkm_clean_socket.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Nach einem make ist das modul fertig und liegt unter dem namen “lkm_clean_socket.ko” im aktuellem verzeichnis.
Wenn alles geklappt hat machen wir folgendes:
# modinfo lkm_clean_socket.ko filename: lkm_clean_socket.ko license: GPL depends: vermagic: 2.6.25-gentoo-r7 SMP mod_unload PENTIUM4 # insmod lkm_clean_socket.ko # dmesg .... ++ Kernel Mode Socket is up ... ++ ERRNO: 0.. ++ Kernel Mode Socket is up an connected... ++ ERRNO: 0.. ++ Kernel Mode Socket is sending stuff... ++ ERRNO: 19.. ++ Kernel Mode Socket is recieving stuff... ++ ERRNO: 1024.. ++ Recieved: HTTP/1.1 200 OK Date: Sat, 30 Aug 2008 00:18:58 GMT Server: Apache X-Powered-By: PHP/5.2.0-8+etch11 X-Pingback: http://sixserv.org/xmlrpc.php Connection: close Content-Type: text/html; charset=UTF-8 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="de-DE"> <head profile="http://gmpg.org/xfn/11"> <title>sixserv blog</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="description" content="welcome to teh #sixserv!" /> <meta name="generator" content="WordPress 2.6.1" /> <!-- leave this for stats please --> <link href="http://sixserv.org/wp-content/themes/journalist/style.css" rel="stylesheet" type="text/css" media="screen" /> <link rel="alternate" type="application/rss+xml" title="sixserv blog RSS Feed" href="http://sixserv.org/feed/" /> <link rel="shortcut icon" type="image/x-png" href="http://sixserv.org/wp-content/the .... # rmmod lkm_clean_socket.ko
Wie man sehen kann ist unser buffer ein wenig zu klein, und die errnos kann man sich eigtl. auch sparen wenn kein Fehler auftritt.
Seid gespannt auf den nächsten teil der kernel mode Serie
nks
quellen:
ps:
cuil.com und metager2.de lassen sich beide in die Suchleiste integrieren (klickt einfach auf den namen dann fragt euch FF). Nach einigem testen gefällt mir metager2 wesentlich besser weil es VIEL mehr findet. Allerdings gefällt mir die Aufmachung von cuil.com, ich sehe noch einiges an potenzial.
pps:
Mal wieder ein musikalischer Tipp:
http://www.myspace.com/blue_nine
edit: Unterschiede zu Version 0.1 haben nur mit der Rechtschreibung zu tun!
Tagged: Development, kernel, Linux, Networking, security
bitlet.org privacy
Ich nutze gerne den BitTorrent-Client “BitLet”, wenn ich an maschinen ohne installierten BiTorrent-Client arbeite. Wirklich genial und einfach. Zeigt sehr schön wie man mit Java auch nicht resourcenfressende Ressourcen-schonende torrent-Clients schreiben kann, im Gegensatz zu Azureus/Vuze. Ich nutze BitLet recht häufig jedoch bereitet mir schon seit längerem sorgen, dass auf der Startseite eine history der letzten torrents liegt. Das ist natürlich sehr praktisch fürs resumen bzw. um den aktuellen stand des Downloads zu sehen und ihn bei bedarf zu loeschen oder zu resumen, allerdings liegen diese taten auf dem Server von BitLet.org.
BitLet hat somit auf ihren Servern eine Datenbank laufen die die IPs logt mit denen die User ihre Downloads tätigen und die entsprechenden namen der .torrent-Files (mit ausgelesenen meta-Daten und download-fortschritt). Das wird vermutlich über ein Cookie realisiert.
Also ab und zu mal Cookies löschen…
Bleibt abzuwarten was sich daraus ergibt.
links:
Tagged: bittorrent, java, privacy, Torrent
kernel mode sockets part 1 (the dirty way)
Version 0.3 – 23.01.2009
Kernel mode sockets sind hoch-interessant. Im ersten teil befasse ich mich mit einer einfachen Implementierung eines ziemlich simplen kernel mode sockets, das ist nicht der Weg wie man es machen sollte allerdings hilft es erstmal dem grundsätzlichem Verständnis von lkm – also kernel modulen unter linux.
Es ist natürlich trotzdem möglich diesen Code in einem rootkit zu verwenden etc. aber ich finde das dieser Code nichts in einem produktiven Umfeld zu suchen hat, man öffnet keine Dateien aus derm kernel mode.
Wir beginnen mit den Basics eines lkm.
Zu erst das klassische “Hello world.”:
/* * lkm_hello_world.c */ #include <linux/module.h> #include <linux/kernel.h> int init_module(void) { printk(KERN_INFO "Hello world.\n"); } void cleanup_module(void) { printk(KERN_INFO "Goodbye world.\n"); }
Zum kompilieren des Moduls legen wir nun ein Makefile an:
obj-m += lkm_hello_world.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Vielleicht hat der ein oder andere versucht die sys/socket.h (etc.) einzubinden, aber das geht nicht. man sollte das auch nicht machen da das user-mode includes sind. Also machen wir weiter, wir erstellen wir einen simplen (dirty) socket im kernel mode. Ich hab mich dazu entschieden das wir den socket über den syscall “socketcall()” erstellen. Um syscalls aus dem kernel aufrufen zu können gab es bis kernel 2.6.19 die syscall macros (für alle mit einem neuerem kernel habe ich einen kleinen header mit den macros hoch geladen), allerdings kann man eigtl keine syscalls vom kernel aus machen, damit wir das können müssen wir aus dem kernel-space Adressraum in den user space Adressraum, das geschieht hier per set_fs(). und schon kann man userspace calls ausführen.
/* * lkm_dirty_socket.c - nks */ #include "syscall_macros.h" /* auskommentieren wenn die kernel version unter 2.6.19/18 ist! */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/socket.h> #include <linux/net.h> #include <linux/in.h> #include <linux/ip.h> #include <linux/netdevice.h> #include <linux/init.h> #include <linux/syscalls.h> #include <linux/fcntl.h> #include <asm/uaccess.h> #include <linux/unistd.h> int errno; /* needed by socketcall() */ /* int socketcall(int call, unsigned long *args); wie wir sehen koennen werden der funktion socketcall() 2 call uebergeben, also benutzen wir das _syscall2-makro: */ static inline _syscall2(int, socketcall, int, call, unsigned long *, args); int init_module(void) { unsigned long arg[3]; int socket; mm_segment_t old_fs; struct sockaddr_in addr; struct sockaddr_in saddr; printk(KERN_INFO "#sixserv/sixserv.org presents:\n"); printk(KERN_INFO "simple kernel mode socket - nks\n"); old_fs = get_fs(); /* die argumente fuer socketcall vorbereiten*/ arg[0] = PF_INET; arg[1] = SOCK_STREAM; arg[2] = 0; set_fs(KERNEL_DS); if ((socket = socketcall(1, arg)) == -1) // SYS_SOCKET = 1 { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is up ...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); } return 0; } void cleanup_module(void) { printk(KERN_INFO "Goodbye world.\n"); }
nun muessen wir die Makefile an das neue modul anpassen
obj-m += lkm_dirty_socket.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Nun können wir mit einem
# make #insmod lkm_dirty_socket
das Modul bauen und laden, mit dmesg sollte man dann die Meldungen sehen ob es geklappt hat sieht man wenn der folgende text in der debug Ausgabe erscheint:
++ Kernel Mode Socket is up …
Aber nur ein socket alleine ist ja bekanntlich ziemlich langweilig ![]()
Also verbinden wir uns mit einem http Server. Hierfür müssen wir noch ein paar Anpassungen an unserem bestehendem Code tätigen:
/* * lkm_dirty_socket.c - nks */ #include "syscall_macros.h" /* auskommentieren wenn die kernel version unter 2.6.19/18 ist! */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/socket.h> #include <linux/net.h> #include <linux/in.h> #include <linux/ip.h> #include <linux/netdevice.h> #include <linux/init.h> #include <linux/syscalls.h> #include <linux/fcntl.h> #include <asm/uaccess.h> #include <linux/unistd.h> int errno; /* needed by socketcall() */ /* int socketcall(int call, unsigned long *args); wie wir sehen koennen werden der funktion socketcall() 2 parameter uebergeben, also benutzen wir das _syscall2-makro: */ static inline _syscall2(int, socketcall, int, call, unsigned long *, args); int init_module(void) { unsigned long arg[3]; int socket; mm_segment_t old_fs; struct sockaddr_in addr; struct sockaddr_in saddr; unsigned long arg1[3]; unsigned long args[4]; char buffer[1024]; printk(KERN_INFO "#sixserv/sixserv.org presents:\n"); printk(KERN_INFO "simple kernel mode socket - nks\n"); old_fs = get_fs(); arg[0] = PF_INET; arg[1] = SOCK_STREAM; arg[2] = 0; set_fs(KERNEL_DS); if ((socket = socketcall(1, arg)) == -1) // SYS_SOCKET = 1 { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is up ...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); } saddr.sin_addr.s_addr = inet_addr("79.140.33.153"); saddr.sin_port = htons(80); saddr.sin_family = AF_INET; /* argumente fuer connect(): int connect(int sockfd, struct sockaddr *serv_addr, int addrlen ); */ arg1[0] = socket; arg1[1] = (unsigned long)&saddr; arg1[2] = (unsigned long)sizeof(saddr); if ((socketcall(SYS_CONNECT, arg1)) == -1) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is up an connected...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); } /* argumente fuer send(): send(int s, const void *buf, size_t len, int flags); */ args[0] = socket; args[1] = "GET / HTTP/1.0\r\n\r\n"; args[2] = strlen("GET / HTTP/1.0\r\n\r\n"); args[3] = 0; if ((socketcall(SYS_SEND, args)) == -1) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "-- ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is sending stuff...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); } /* argumente fuer recv(): int recv(int s, void *buf, size_t len, int flags); */ args[0] = socket; args[1] = (unsigned long) buffer; args[2] = 1024; args[3] = 0; if ((socketcall(SYS_RECV, args)) == -1) { printk(KERN_INFO "-- Kernel Mode Socket ERROR...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); set_fs(old_fs); return 0; } else { printk(KERN_INFO "++ Kernel Mode Socket is recieving stuff...\n"); printk(KERN_INFO "++ ERRNO: %d..\n",errno); printk(KERN_INFO "++ Recieved: %s..\n",buffer); } set_fs(old_fs); return 0; } void cleanup_module(void) { printk(KERN_INFO "Goodbye world.\n"); } unsigned int inet_addr(char *str) { int a,b,c,d; char arr[4]; sscanf(str,"%d.%d.%d.%d",&a,&b,&c,&d); arr[0] = a; arr[1] = b; arr[2] = c; arr[3] = d; return *(unsigned int*)arr; }
Wieder ist eine neue Funktion hinzugekommen inet_addr, aber viel interessanter sind die neuen socketcalls, beim lesen kann man anhand des call-Arguments gut sehen welche socket-Funktion nun aufgerufen wird. zur Übergabe der Parameter verwenden wir ein char array bzw zwei da recv und send jeweils 4 Argumente haben.
Die syscall macros hab ich für euch hochgeladen
quellen:
- http://www.linuxjournal.com/node/8110/print
- http://www.ibm.com/developerworks/linux/library/l-system-calls/
- http://www.ibm.com/developerworks/linux/library/l-lkm/
- http://www.gnugeneration.com/mirrors/kernel-api/book1.html
- http://www.tldp.org/LDP/lkmpg/2.6/html/
- http://www.ussg.iu.edu/hypermail/linux/kernel/0303.2/2007.html (inet_addr())
- http://google.com/codesearch/
- http://lkml.org
- http://kerneltrap.org
- /usr/src/linux/*
- syscall_macros.h
Bei fragen etc. kommt doch einfach ins irc (#nullserv/#sixserv im freenode)
nks
ps:
benutzt öfters mal google-alternativen..
http://cuil.com oder http://metager2.de
pps:
chillig, und wie ich finde sehr geil: http://www.myspace.com/17thboulevard
bin gespannt auf das album…
Tagged: Development, kernel, Linux, Networking, security