mpls-agent-devel Mailing List for A SNMP agent for MPLS for Linux
A SNMP agent for management of MPLS for Linux .
Status: Beta
Brought to you by:
jrussi
You can subscribe to this list here.
2006 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
(5) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|
From: Josdeyvi R. <jr...@uo...> - 2006-05-10 14:29:10
|
Hi, To do it, you must create one or more sub-agents for the NET-SNMP agent. = Let me show how with one example from my code, for example, a SNMP GET = of the object mplsInSegmentNPop from the table mplsInSegmentTable = from MIB MPLS-LSR: 1 - What the MIB (RFC3813) says:=20 mplsInSegmentNPop OBJECT-TYPE SYNTAX Integer32 (1..2147483647) MAX-ACCESS read-create STATUS current DESCRIPTION "The number of labels to pop from the incoming packet. Normally only the top label is popped from the packet and used for all switching decisions for that packet. This is indicated by setting this object to the default value of 1. If an LSR supports popping of more than one label, this object MUST be set to that number. This object cannot be modified if mplsInSegmentRowStatus is active(1)." DEFVAL { 1 } ::=3D { mplsInSegmentEntry 5 } 2 - Where can I get it at MPLS for = Linux? [root@MPLSEDGE20~]# mpls ilm show ILM entry label gen 200 labelspace 0 proto ipv4 pop pop pop peek (909056 bytes, 14204 pkts, 0 dropped) This means that for this entry you must have: mplsInSegmentNPop =3D 3 (since you have "pop pop pop") 3 - How was it implemented at the C code?. Please open = "mplsInSegmentTable.c" and "mpls.c". All tables at our SNMP agent are C = linked lists. You must add and delete entries (rows) on those linked = lists in order to reflect the router status as the MIB says. 3.1 - The mplsInSegmentTable We must have two linked lists with the object values of this = table, in order we can keep information about entries in SNMP state "Not = in Service" or "Not Ready" and to compare this SNMP table with the = current state of the router, so it is possible to detect external = changes (made by console commands, for example) and change the MIB table = information as needed to reflect it. 3.1.1 - First list The first list is an HISTORIC table, that keeps entries with = SNMP row state RS_ACTIVE, RS_NOTINSERVICE and RS_NOTREADY. We can use = this list to find one object by means of its indexes and directly feed = other SNMP tables with it=B4s value. It is a C "linked list" with a head pointing to the first = element of the list. There are some help functions to work with linked = lists, to create, insert and remove entries from this linked list, based = on the indexes of the object (insert_index, remove_index, find_index). = You will find those aux functions at "mplsAux.c".=20 At "mpls.c" it is defined a pointer (head) of this linked list: struct head_lst * mplsInIndexList=3DNULL; And then the list is created with a call to the function = new_lst: mplsInIndexList =3D new_lst(); Understanding: The mplsInIndexList->begin is a pointer to the first = entry of the linked list. Each entry of the list is a "struct ndx_lst" = (see "mplsAux.h"), and this entry has a pointer to the next entry (row), = and so on... (got it?). The elements and structure of this linked list are mapped to the rows of = the MIB table. Each entry in the list pointed by mplsInIndexList is a = row of the MIB table. So, we can do, just for an example: ptr =3D mplsInIndexList->begin; .... vars_tmp2 =3D SNMP_MALLOC_TYPEDEF(struct mplsInSegmentTable_entry); // = we will see this table explanation in the next topic ...... vars_tmp2->mplsInSegmentNPop =3D ptr->pushpop; ..... 3.1.2 Second list: the NET SNMP agent table This table is the table used by the NET SNMP agent to respond to = GET and SET commands. This is the linked list where the NET SNMP agent = will look for information to answer for GET and SET SNMP commands. This = linked list codification is created using the "mib2c" program from = net-snmp. Please, see: = http://net-snmp.sourceforge.net/tutorial/tutorial-5/toolkit/mib_module/in= dex.html. I used the mib2c.iterate.conf template, but with some = modification. When you use this template, you will create an struct = similar to this: /* * Typical data structure for a row entry=20 */ struct mplsInSegmentTable_entry { /* * Index values=20 */ u_long mplsInSegmentIndex; /* * Column values=20 */ long mplsInSegmentInterface; u_long mplsInSegmentLabel; oid mplsInSegmentLabelPtr; long mplsInSegmentNPop; long mplsInSegmentAddrFamily; u_long mplsInSegmentXCIndex; long mplsInSegmentOwner; oid mplsInSegmentTrafficParamPtr; int mplsInSegmentRowStatus; int mplsInSegmentStorageType; /* * Illustrate using a simple linked list=20 */ struct mplsInSegmentTable_entry *next; }; struct mplsInSegmentTable_entry *mplsInSegmentTable_head; For this mpls-agent, I chose not to keep the information at this table. = Whenever we have a new GET or SET command, I reset this list and create = a new one, using information from the router and information from the = first list, that keeps RS_NOTINSERVICE and RS_NOTREADY status. I mean, = my work table (list) is the first one, because I found up it was easier = to control.=20 Just one warning about the mib2c.iterate.conf template. It is just a = template, it has errors, you should correct them and modify it for your = use. 3.2 How to fill the linked lists (tables) The "mpls.c" calls a function "init_mplsInSegmentTable()" to register = this sub-agent to the NET-SNMP main agent. If you give a look at the = "init_mplsInSegmentTable()" (see "mplsInSegmentTable.c") You will see: //Local cache netsnmp_inject_handler( reg, netsnmp_get_cache_handler(MIB_STATS_CACHE_TIMEOUT, mplsInSegmentTable_load, mplsInSegmentTable_free, mplsInSegmentTable_oid, OID_LENGTH(mplsInSegmentTable_oid))); =20 mplsInSegmentTable_head =3D mplsInSegmentTable_fill(); //First = initialization This handler says how the sub-agent must fill the table when it receives = a GET or SET, after a timeout. It must call the mplsInSegmentTable_load = function. The mplsInSegmentTable_load is: int mplsInSegmentTable_load(netsnmp_cache *cache, void *vmagic) { =20 mplsInSegmentTable_head =3D mplsInSegmentTable_fill(); DEBUGMSGTL(("LOAD", "Loaded mplsInSegmentTable\n")); return 0; } Gotcha! the function that reads the current status of the router is = mplsInSegmentTable_fill(). Let=B4s see how it works: 3.2.1 - Gathering the router information Here one can choose use the RT-NETLINK protocol or use the mpls command = output. With RT-NETLINK protocol, you get the information directly from = the kernel, in the same way that the "mpls ilm show" command does. To do = it, you must know how and where the internal structures of the MPLS for = Linux are. And you must to pray that this will not change from one = version to other (as it occurred from 1.946 to 1.950). If you want to = try, hack the: linux-kernel.diff=20 iproute2.diff from MPLS for Linux. At iproute2.diff for example, the function = "print_ilm" will show how to use NETLINK to catch the internal ILM table = information, the same way as the "mpls" command does. Since the version 1.946 was the first to use the NETLINK, I thinked that = it would be easier and safe NOT to use the NETLINK protocol. =20 To use the "mpls" output, you must parse the output. This way (at = mplsInSegmentTable_fill(); ) : DEBUGMSGTL(("LOAD", "IN: get ILM entries \n ")); system(">/tmp/mpls.ilm"); system("mpls ilm show >> /tmp/mpls.ilm"); =20 fd =3D fopen("/tmp/mpls.ilm","rb"); ... while ((fgets(line,256,fd)) !=3DNULL) { if ((cmd=3Dstrstr (line,"ILM"))!=3DNULL) { sscanf(cmd,"ILM entry label %*s %lu %*s %lu proto = %s",&label,&labelspace,proto); =20 .... // Here we count the number of POPs: if (((cmd=3Dstrstr (line,"pop"))!=3DNULL) && (ifindex!=3D-1)){ i=3D0; while (cmd !=3D NULL) { strncpy(cmd,"cmd",3); cmd=3Dstrstr(line,"pop"); i++; } vars_tmp2->mplsInSegmentNPop =3D i;=20 newnode->pushpop =3D vars_tmp2->mplsInSegmentNPop; // Insert the new row at the work table (list) newnode->valid=3D1; insert_index(newnode,mplsInIndexList); =20 //Insert the new row at the NET-SNMP list vars_tmp2->next =3D vars_tmp; vars_tmp =3D vars_tmp2; // Load the RS_NOTINSERVICE and RS_NOTREADY from the work table to the = NET-SNMP table // As this information will not come from the router (is not active) // We keep it at our work table. DEBUGMSGTL(("LOAD", "IN: Clean up list of indexes\n ")); cleanup_lst(mplsInIndexList); DEBUGMSGTL(("LOAD", "IN: Clean up done\n ")); DEBUGMSGTL(("LOAD", "IN: Loading RS_NOTINSERVICE and RS_NOTREADY = entries\n ")); ptr =3D mplsInIndexList->begin; if (ptr !=3D NULL) do {=20 aux=3Dptr->next; if ((ptr->RowStatus =3D=3D RS_NOTINSERVICE) || (ptr->RowStatus = =3D=3D RS_NOTREADY)){ // if (ptr->RowStatus =3D=3D RS_NOTINSERVICE){ vars_tmp2 =3D SNMP_MALLOC_TYPEDEF(struct mplsInSegmentTable_entry); vars_tmp2->mplsInSegmentIndex =3D ptr->index; vars_tmp2->mplsInSegmentInterface =3D ptr->interface; vars_tmp2->mplsInSegmentLabel =3D ptr->label; vars_tmp2->mplsInSegmentNPop =3D ptr->pushpop; vars_tmp2->mplsInSegmentXCIndex =3D ptr->xc; vars_tmp2->mplsInSegmentOwner =3D ptr->owner;=20 vars_tmp2->mplsInSegmentAddrFamily =3D ptr->family;// XXX TODO IPv6 = support vars_tmp2->mplsInSegmentRowStatus =3D ptr->RowStatus; vars_tmp2->mplsInSegmentStorageType=3D 2 ; vars_tmp2->next =3D vars_tmp; vars_tmp =3D vars_tmp2; } ptr=3Daux; } while (ptr !=3DNULL); =20 DEBUGMSGTL(("LOAD", "IN: Load Done!\n ")); return vars_tmp; } And that=B4s all. The NET-SNMP table is filled and ready to answer for = the GET commands. This is done at the mplsInSegmentTable_handler(); = function. Give a look there, it is not complicate to understand. Hope this can help you to start your work. The SET commands are all = worked at mplsInSegmentTable_handler(); To understand how it works, read = the tutorial at: = http://net-snmp.sourceforge.net/tutorial/tutorial-5/toolkit/mib_module/in= dex.html The SET is: 1 - Receive the command=20 2 - Validate it ("case MODE_SET_RESERVE1:" and "case = MODE_SET_RESERVE2:") 3 - If it is OK, act ("case MODE_SET_ACTION:") Good luck, tell me your progress! Josdeyvi |
From: <kis...@wi...> - 2006-04-25 04:17:31
|
Sir =20 I need to develop a SNMP agent for the MIB defined for objects = like=20 =20 mplsLspName =20 mplsLspAge =20 mplsLspTimeUp =20 mplsLspFrom =20 mplsLspTo =20 mplsPathName =20 mplsPathBandwidth =20 mplsPathJitter =20 mplsPathDelay =20 mplsPathLosses =20 mplsPathLatency =20 =20 Where should I modify the SNMP agent code you developed one to suite to = the MIB above?.. How to fetch bandwidth, delay ,jitter info from the = kernel? =20 Regards, Kishor =20 =20 =20 |
From: <kis...@wi...> - 2006-04-21 15:13:19
|
Thanks a lot. I need to develop a SNMP agent for the MIB defined for objects like=20 mplsLspName =20 mplsLspAge =20 mplsLspTimeUp =20 mplsLspFrom =20 mplsLspTo =20 mplsPathName =20 mplsPathBandwidth =20 mplsPathJitter =20 mplsPathDelay =20 mplsPathLosses =20 mplsPathLatency =20 =20 Where should I modify the SNMP agent code you developed one to suite to the MIB above?.. How to fetch bandwidth,delay ,jitter info from the kernel? -----Original Message----- From: James R. Leu [mailto:jl...@mi...]=20 Sent: Friday, April 21, 2006 8:02 PM To: Kishor Krishna Cc: mpl...@li...; mpl...@li... Subject: Re: [mpls-linux-general] help in accesing label table The C code for accessing MPLS objects via netlink can be downloaded=20 in the source RPMs from http://sf.net/projects/mpls-linux in the file section. On Fri, Apr 21, 2006 at 05:08:33PM +0530, kis...@wi... wrote: > =20 > =20 > I developing a SNMP agent to control and monitor Service level agreements in MPLS network. So I installed MPLS in my fedora 2 system. Also the project involves developing QOS objects such as bandwidth, delay, jitter, losses, latency etc. I am not able to get label table here. (ilm, nhlfe, xc).. Someone can send me C code to access label table from userspace using netlink?..I would be really grateful if someone sends me the working C code as its urgent. > =20 > Thanking You, > Kishor --=20 James R. Leu jl...@mi... |
From: James R. L. <jl...@mi...> - 2006-04-21 14:32:55
|
The C code for accessing MPLS objects via netlink can be downloaded=20 in the source RPMs from http://sf.net/projects/mpls-linux in the file section. On Fri, Apr 21, 2006 at 05:08:33PM +0530, kis...@wi... wrote: > =20 > =20 > I developing a SNMP agent to control and monitor Service level agreements= in MPLS network. So I installed MPLS in my fedora 2 system. Also the proje= ct involves developing QOS objects such as bandwidth, delay, jitter, losses= , latency etc. I am not able to get label table here. (ilm, nhlfe, xc).. So= meone can send me C code to access label table from userspace using netlink= ?..I would be really grateful if someone sends me the working C code as its= urgent. > =20 > Thanking You, > Kishor --=20 James R. Leu jl...@mi... |
From: <kis...@wi...> - 2006-04-21 11:37:20
|
=20 =20 I developing a SNMP agent to control and monitor Service level = agreements in MPLS network. So I installed MPLS in my fedora 2 system. = Also the project involves developing QOS objects such as bandwidth, = delay, jitter, losses, latency etc. I am not able to get label table = here. (ilm, nhlfe, xc).. Someone can send me C code to access label = table from userspace using netlink?..I would be really grateful if = someone sends me the working C code as its urgent. =20 Thanking You, Kishor |
From: <kis...@wi...> - 2006-04-12 09:03:21
|
=20 =20 =20 =20 Sir Thanks a lot. I need to develop a SNMP agent for the MIB defined = for objects like=20 mplsLspName =20 mplsLspAge =20 mplsLspTimeUp =20 mplsLspFrom =20 mplsLspTo =20 mplsPathName =20 mplsPathBandwidth =20 mplsPathJitter =20 mplsPathDelay =20 mplsPathLosses =20 mplsPathLatency =20 =20 Where should I modify the SNMP agent code you developed one to suite to = the MIB above?.. How to fetch bandwidth,delay ,jitter info from the = kernel? =20 Regards, Kishor =20 =20 =20 =20 -----Original Message----- From: Josdeyvi Russi [mailto:jr...@uo...]=20 Sent: Friday, February 24, 2006 2:13 AM To: Kishor Krishna Cc: mpl...@li... Subject: Re: Re: [mpls-linux-general] command help =20 Hi Kishor, =20 For the label table the MIB MPLS-LSR have 3 major tables: = mplsInSegmentTable, mplsOutSegmentTable, mplsXCTable. To populate these = tables, your SNMP Agent must read the ilm, nhlfe and xc internal tables = from MPLS for Linux and put the things in the correct place. =20 For example, if I do a set of commands like: =20 =20 # mpls labelspace add dev eth1 labelspace 0 # mpls ilm add label gen 100 labelspace 0 I will get the following ILM table: [root@MPLSCORE~]# mpls ilm sh ILM entry label gen 100 labelspace 0 proto ipv4=20 pop forward key 0x00000002 (385664 bytes, 6026 pkts, 0 dropped) And my Labelspace will be: [root@MPLSCORE~]# mpls labelspace sh LABELSPACE entry dev eth1 labelspace 0 The SNMP agent then must READ this output in somehow. You can directly = acess the kernel using RTNetlink protocol (hack the mpls command of MPLS = for Linux to learn how to do it) ou simple read and scan the output = lines in your program. Doing it you must have the following at your MIB = browser: [root@MPLSCORE~]# snmpwalk -v2c -c public -O T -O S -O n localhost = MPLSLSRSTDMIB::mplsInSegmentTable .1.3.6.1.2.1.10.166.2.1.4.1.2.4.0.0.0.1 =3D INTEGER: 0 .1.3.6.1.2.1.10.166.2.1.4.1.3.4.0.0.0.1 =3D Gauge32: 100 .1.3.6.1.2.1.10.166.2.1.4.1.4.4.0.0.0.1 =3D OID: .0.0 .1.3.6.1.2.1.10.166.2.1.4.1.5.4.0.0.0.1 =3D INTEGER: 1 .1.3.6.1.2.1.10.166.2.1.4.1.6.4.0.0.0.1 =3D INTEGER: ipV4(1) .1.3.6.1.2.1.10.166.2.1.4.1.7.4.0.0.0.1 =3D HexSTRING: 34 2E 30 2E 30 2E 30 2E 32 00 FF BF AA D8 EB 43 [4.0.0.0.2......C]=20 .1.3.6.1.2.1.10.166.2.1.4.1.8.4.0.0.0.1 =3D INTEGER: other(2) .1.3.6.1.2.1.10.166.2.1.4.1.9.4.0.0.0.1 =3D OID: .0.0 .1.3.6.1.2.1.10.166.2.1.4.1.10.4.0.0.0.1 =3D INTEGER: active(1) .1.3.6.1.2.1.10.166.2.1.4.1.11.4.0.0.0.1 =3D INTEGER: volatile(2) =20 I recommend you to read the following book: =20 Nadeu, Thomas D., "MPLS Network Management", 2003, Morgan Kaufmann = Publishers. =20 Good luck! =20 Josdeyvi Russi =20 =20 ---------------------------------------------- The scope stuff is not mpls-linux specific, read the iproute2 documents for info about 'scope'. There is a SF project that implements a SNMP agent for mpls-linux. Do a search on the SF site for mpls and it will be one of the matches. BTW SF =3D3D=3D3D sourceforge.net On Wed, Feb 22, 2006 at 10:24:27AM +0530, kis...@wi... = wrote: > Hii > =3D20 > =3D20 > I didn't get what do mean scope link in > " > 10.200.19.1 via 10.200.19.1 dev eth0 spec_nh 0x8847 0x2 > 192.168.2.9/24 dev eth0 scope link > 10.200.19.1/24 dev eth0 proto kernel scope link src = 10.200.19,.1=3D20 > 127.0.0.0/8 dev lo scope link" > =3D20 > One more thing how can I access label table from SNMP agent? = Specifically=3D are there any functions or commands for this?. Help me > =3D20 > Thanks and Regards, > =3D20 > Kishor > =3D20 --=3D20 James R. Leu jl...@mi... The information contained in this electronic message and any attachments = to this message are intended for the exclusive use of the addressee(s) = and may contain proprietary, confidential or privileged information. If = you are not the intended recipient, you should not disseminate, = distribute or copy this e-mail. Please notify the sender immediately and = destroy all copies of this message and any attachments.=20 WARNING: Computer viruses can be transmitted via email. The recipient = should check this email and any attachments for the presence of viruses. = The company accepts no liability for any damage caused by any virus = transmitted by this email. www.wipro.com =20 |
From: <kis...@wi...> - 2006-03-27 11:55:17
|
=20 =20 =20 =20 Sir Thanks a lot. I need to develop a SNMP agent for the MIB defined = for objects like=20 mplsLspName =20 mplsLspAge =20 mplsLspTimeUp =20 mplsLspFrom =20 mplsLspTo =20 mplsPathName =20 mplsPathBandwidth =20 mplsPathJitter =20 mplsPathDelay =20 mplsPathLosses =20 mplsPathLatency =20 =20 Where should I modify the SNMP agent code you developed one to suite to = the MIB above?.. How to fetch bandwidth,delay ,jitter info from the = kernel? =20 Regards, Kishor =20 =20 =20 =20 -----Original Message----- From: Josdeyvi Russi [mailto:jr...@uo...]=20 Sent: Friday, February 24, 2006 2:13 AM To: Kishor Krishna Cc: mpl...@li... Subject: Re: Re: [mpls-linux-general] command help =20 Hi Kishor, =20 For the label table the MIB MPLS-LSR have 3 major tables: = mplsInSegmentTable, mplsOutSegmentTable, mplsXCTable. To populate these = tables, your SNMP Agent must read the ilm, nhlfe and xc internal tables = from MPLS for Linux and put the things in the correct place. =20 For example, if I do a set of commands like: =20 =20 # mpls labelspace add dev eth1 labelspace 0 # mpls ilm add label gen 100 labelspace 0 I will get the following ILM table: [root@MPLSCORE~]# mpls ilm sh ILM entry label gen 100 labelspace 0 proto ipv4=20 pop forward key 0x00000002 (385664 bytes, 6026 pkts, 0 dropped) And my Labelspace will be: [root@MPLSCORE~]# mpls labelspace sh LABELSPACE entry dev eth1 labelspace 0 The SNMP agent then must READ this output in somehow. You can directly = acess the kernel using RTNetlink protocol (hack the mpls command of MPLS = for Linux to learn how to do it) ou simple read and scan the output = lines in your program. Doing it you must have the following at your MIB = browser: [root@MPLSCORE~]# snmpwalk -v2c -c public -O T -O S -O n localhost = MPLSLSRSTDMIB::mplsInSegmentTable .1.3.6.1.2.1.10.166.2.1.4.1.2.4.0.0.0.1 =3D INTEGER: 0 .1.3.6.1.2.1.10.166.2.1.4.1.3.4.0.0.0.1 =3D Gauge32: 100 .1.3.6.1.2.1.10.166.2.1.4.1.4.4.0.0.0.1 =3D OID: .0.0 .1.3.6.1.2.1.10.166.2.1.4.1.5.4.0.0.0.1 =3D INTEGER: 1 .1.3.6.1.2.1.10.166.2.1.4.1.6.4.0.0.0.1 =3D INTEGER: ipV4(1) .1.3.6.1.2.1.10.166.2.1.4.1.7.4.0.0.0.1 =3D HexSTRING: 34 2E 30 2E 30 2E 30 2E 32 00 FF BF AA D8 EB 43 [4.0.0.0.2......C]=20 .1.3.6.1.2.1.10.166.2.1.4.1.8.4.0.0.0.1 =3D INTEGER: other(2) .1.3.6.1.2.1.10.166.2.1.4.1.9.4.0.0.0.1 =3D OID: .0.0 .1.3.6.1.2.1.10.166.2.1.4.1.10.4.0.0.0.1 =3D INTEGER: active(1) .1.3.6.1.2.1.10.166.2.1.4.1.11.4.0.0.0.1 =3D INTEGER: volatile(2) =20 I recommend you to read the following book: =20 Nadeu, Thomas D., "MPLS Network Management", 2003, Morgan Kaufmann = Publishers. =20 Good luck! =20 Josdeyvi Russi =20 =20 ---------------------------------------------- The scope stuff is not mpls-linux specific, read the iproute2 documents for info about 'scope'. There is a SF project that implements a SNMP agent for mpls-linux. Do a search on the SF site for mpls and it will be one of the matches. BTW SF =3D3D=3D3D sourceforge.net On Wed, Feb 22, 2006 at 10:24:27AM +0530, kis...@wi... = wrote: > Hii > =3D20 > =3D20 > I didn't get what do mean scope link in > " > 10.200.19.1 via 10.200.19.1 dev eth0 spec_nh 0x8847 0x2 > 192.168.2.9/24 dev eth0 scope link > 10.200.19.1/24 dev eth0 proto kernel scope link src = 10.200.19,.1=3D20 > 127.0.0.0/8 dev lo scope link" > =3D20 > One more thing how can I access label table from SNMP agent? = Specifically=3D are there any functions or commands for this?. Help me > =3D20 > Thanks and Regards, > =3D20 > Kishor > =3D20 --=3D20 James R. Leu jl...@mi... The information contained in this electronic message and any attachments = to this message are intended for the exclusive use of the addressee(s) = and may contain proprietary, confidential or privileged information. If = you are not the intended recipient, you should not disseminate, = distribute or copy this e-mail. Please notify the sender immediately and = destroy all copies of this message and any attachments.=20 WARNING: Computer viruses can be transmitted via email. The recipient = should check this email and any attachments for the presence of viruses. = The company accepts no liability for any damage caused by any virus = transmitted by this email. www.wipro.com =20 |
From: Josdeyvi R. <jr...@uo...> - 2006-01-29 14:46:48
|
Beta version released |