Преглед изворни кода

* Made a crazy attempt to at least partially synchronize login&char code
* Major edit to the way the servers handle ip addresses, making them obey the "host byte order inside, network byte order outside" rule
- hopefully covered all entry- and exit-points for IP address data
- discovered several places where Gravity's client breaks the convention, will need to come up with a suitable countermeasure for that
- other than that, the code should be portable, except for printing and ipban mask testing (those still assume a specific byte order)
- tested both txt and sql in all usual situations; tested single- and multi-server setups, all seems to work (but watch out for hidden bugs!)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10162 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage пре 18 година
родитељ
комит
8dc1b77f03
19 измењених фајлова са 983 додато и 1178 уклоњено
  1. 11 0
      Changelog-Trunk.txt
  2. 188 203
      src/char/char.c
  3. 197 276
      src/char_sql/char.c
  4. 2 2
      src/common/mmo.h
  5. 34 36
      src/common/socket.c
  6. 9 9
      src/common/socket.h
  7. 25 21
      src/common/strlib.c
  8. 6 11
      src/common/strlib.h
  9. 18 28
      src/common/utils.c
  10. 200 254
      src/login/login.c
  11. 180 181
      src/login_sql/login.c
  12. 2 2
      src/login_sql/login.h
  13. 54 93
      src/map/chrif.c
  14. 6 6
      src/map/chrif.h
  15. 23 28
      src/map/clif.c
  16. 5 5
      src/map/clif.h
  17. 10 11
      src/map/map.c
  18. 5 5
      src/map/map.h
  19. 8 7
      src/map/pc.c

+ 11 - 0
Changelog-Trunk.txt

@@ -3,6 +3,17 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2007/04/06
+	* Made a crazy attempt to at least partially synchronize login&char code
+	* Major edit to the way the servers handle ip addresses, making them obey
+	  the "host byte order inside, network byte order outside" rule [ultramage]
+	- hopefully covered all entry- and exit-points for IP address data
+	- discovered several places where Gravity's client breaks the convention,
+	  will need to come up with a suitable countermeasure for that
+	- other than that, the code should be portable, except for printing and
+	  ipban mask testing (those still assume a specific byte order)
+	- tested both txt and sql in all usual situations; tested single- and
+	  multi-server setups, all seems to work (but watch out for hidden bugs!)
 2007/04/05
 	* Cleaned @whogm. It will display the name of all gms online. If their GM
 	  level is above your own, it will only display their name, otherwise level,

Разлика између датотеке није приказан због своје велике величине
+ 188 - 203
src/char/char.c


Разлика између датотеке није приказан због своје велике величине
+ 197 - 276
src/char_sql/char.c


+ 2 - 2
src/common/mmo.h

@@ -215,8 +215,8 @@ struct mmo_charstatus {
 	short str,agi,vit,int_,dex,luk;
 	unsigned char char_num,sex;
 
-	unsigned long mapip;
-	unsigned int mapport;
+	uint32 mapip;
+	uint16 mapport;
 
 	struct point last_point,save_point,memo_point[MAX_MEMOPOINTS];
 	struct item inventory[MAX_INVENTORY],cart[MAX_CART];

+ 34 - 36
src/common/socket.c

@@ -242,7 +242,7 @@ int connect_client(int listen_fd)
 
 	len = sizeof(client_address);
 
-	fd = accept(listen_fd,(struct sockaddr*)&client_address,&len);
+	fd = accept(listen_fd, (struct sockaddr*)&client_address, &len);
 	if ( fd == INVALID_SOCKET ) {
 		ShowError("accept failed (code %i)!\n", s_errno);
 		return -1;
@@ -258,7 +258,7 @@ int connect_client(int listen_fd)
 	set_nonblocking(fd, 1);
 
 #ifndef MINICORE
-	if( ip_rules && !connect_check(*(uint32*)(&client_address.sin_addr)) ){
+	if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) {
 		do_close(fd);
 		return -1;
 	}
@@ -270,13 +270,13 @@ int connect_client(int listen_fd)
 		fd_max = fd + 1;
 
 	create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse);
-	session[fd]->client_addr = client_address;
+	session[fd]->client_addr = ntohl(client_address.sin_addr.s_addr);
 	session[fd]->rdata_tick = last_tick;
 
 	return fd;
 }
 
-int make_listen_bind(long ip,int port)
+int make_listen_bind(uint32 ip, uint16 port)
 {
 	struct sockaddr_in server_address;
 	int fd;
@@ -293,8 +293,8 @@ int make_listen_bind(long ip,int port)
 	set_nonblocking(fd, 1);
 
 	server_address.sin_family      = AF_INET;
-	server_address.sin_addr.s_addr = ip;
-	server_address.sin_port        = htons((unsigned short)port);
+	server_address.sin_addr.s_addr = htonl(ip);
+	server_address.sin_port        = htons(port);
 
 	result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
 	if( result == SOCKET_ERROR ) {
@@ -320,7 +320,7 @@ int make_listen_bind(long ip,int port)
 	return fd;
 }
 
-int make_connection(long ip, int port)
+int make_connection(uint32 ip, uint16 port)
 {
 	struct sockaddr_in server_address;
 	int fd;
@@ -335,12 +335,11 @@ int make_connection(long ip, int port)
 
 	setsocketopts(fd);
 
-	server_address.sin_family = AF_INET;
-	server_address.sin_addr.s_addr = ip;
-	server_address.sin_port = htons((unsigned short)port);
+	server_address.sin_family      = AF_INET;
+	server_address.sin_addr.s_addr = htonl(ip);
+	server_address.sin_port        = htons(port);
 
-	ShowStatus("Connecting to %d.%d.%d.%d:%i\n",
-		(ip)&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,(ip>>24)&0xFF,port);
+	ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port);
 
 	result = connect(fd, (struct sockaddr *)(&server_address), sizeof(struct sockaddr_in));
 	if( result == SOCKET_ERROR ) {
@@ -389,7 +388,7 @@ int delete_session(int fd)
 	return 0;
 }
 
-int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size)
+int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size)
 {
 	if( !session_isValid(fd) )
 		return 0;
@@ -421,7 +420,7 @@ int realloc_writefifo(int fd, size_t addition)
 	else if( session[fd]->max_wdata >= FIFOSIZE_SERVERLINK) {
 		//Inter-server adjust. [Skotlex]
 		if ((session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata)
-			newsize = session[fd]->max_wdata/2;
+			newsize = session[fd]->max_wdata / 2;
 		else
 			return 0; //No change
 	} else if( session[fd]->max_wdata > wfifo_size && (session[fd]->wdata_size+addition)*4 < session[fd]->max_wdata )
@@ -437,7 +436,7 @@ int realloc_writefifo(int fd, size_t addition)
 	return 0;
 }
 
-int RFIFOSKIP(int fd,int len)
+int RFIFOSKIP(int fd, int len)
 {
     struct socket_data *s;
 
@@ -468,11 +467,10 @@ int WFIFOSET(int fd, int len)
 	// we have written len bytes to the buffer already before calling WFIFOSET
 	if(s->wdata_size+len > s->max_wdata)
 	{	// actually there was a buffer overflow already
-		unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
-		ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n", fd,
-			sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3], len, s->wdata_size, s->max_wdata);
-		ShowDebug("Likely command that caused it: 0x%x\n",
-			(*(unsigned short*)(s->wdata + s->wdata_size)));
+		uint32 ip = s->client_addr;
+		ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n",
+			fd, CONVIP(ip), len, s->wdata_size, s->max_wdata);
+		ShowDebug("Likely command that caused it: 0x%x\n", (*(unsigned short*)(s->wdata + s->wdata_size)));
 		// no other chance, make a better fifo model
 		exit(1);
 	}
@@ -645,15 +643,13 @@ static int access_order    = ACO_DENY_ALLOW;
 static int access_allownum = 0;
 static int access_denynum  = 0;
 static int access_debug    = 0;
-static int ddos_count     = 10;
-static int ddos_interval  = 3*1000;
-static int ddos_autoreset = 10*60*1000;
+static int ddos_count      = 10;
+static int ddos_interval   = 3*1000;
+static int ddos_autoreset  = 10*60*1000;
 /// Connection history, an array of linked lists.
 /// The array's index for any ip is ip&0xFFFF
 static ConnectHistory* connect_history[0x10000];
 
-#define CONVIP(ip) ip&0xFF,(ip>>8)&0xFF,(ip>>16)&0xFF,ip>>24
-
 static int connect_check_(uint32 ip);
 
 /// Verifies if the IP can connect. (with debug info)
@@ -816,7 +812,7 @@ int access_ipmask(const char* str, AccessControl* acc)
 	unsigned int m[4];
 	int n;
 
-	if( strcmp(str,"all") == 0 ){
+	if( strcmp(str,"all") == 0 ) {
 		ip   = 0;
 		mask = 0;
 	} else {
@@ -856,7 +852,7 @@ int access_ipmask(const char* str, AccessControl* acc)
 #endif
 //////////////////////////////
 
-int socket_config_read(const char *cfgName)
+int socket_config_read(const char* cfgName)
 {
 	char line[1024],w1[1024],w2[1024];
 	FILE *fp;
@@ -960,7 +956,7 @@ void do_close(int fd)
 
 /// Retrieve local ips in host byte order.
 /// Uses loopback is no address is found.
-int socket_getips(uint32 *ips, int max)
+int socket_getips(uint32* ips, int max)
 {
 	int num = 0;
 
@@ -986,7 +982,7 @@ int socket_getips(uint32 *ips, int max)
 		{
 			hent = gethostbyname(fullhost);
 			if( hent == NULL ){
-				ShowError("socket_getips: Cannot resolve our own hostname to a IP address\n");
+				ShowError("socket_getips: Cannot resolve our own hostname to an IP address\n");
 				return 0;
 			}
 			a = (u_long**)hent->h_addr_list;
@@ -1099,16 +1095,18 @@ int session_isActive(int fd)
 	return ( session_isValid(fd) && !session[fd]->eof );
 }
 
-
-in_addr_t host2ip(const char* hostname)
+// Resolves hostname into a numeric ip.
+uint32 host2ip(const char* hostname)
 {
 	struct hostent* h = gethostbyname(hostname);
-	return (h != NULL) ? *(in_addr_t*)h->h_addr : 0;
+	return (h != NULL) ? ntohl(*(uint32*)h->h_addr) : 0;
 }
 
-const char* ip2str(in_addr_t ip, char ip_str[16])
+// Converts a numeric ip into a dot-formatted string.
+// Result is placed either into a user-provided buffer or a static system buffer.
+const char* ip2str(uint32 ip, char ip_str[16])
 {
-	in_addr_t addr = ntohl(ip);
-	sprintf(ip_str, "%d.%d.%d.%d", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF);
-	return ip_str;
+	struct in_addr addr;
+	addr.s_addr = htonl(ip);
+	return (ip_str == NULL) ? inet_ntoa(addr) : strncpy(ip_str, inet_ntoa(addr), 16);
 }

+ 9 - 9
src/common/socket.h

@@ -81,7 +81,7 @@ struct socket_data {
 	size_t rdata_size, wdata_size;
 	size_t rdata_pos;
 	time_t rdata_tick; // time of last receive (for detecting timeouts)
-	struct sockaddr_in client_addr; // remote client address (zero for s2s connections)
+	uint32 client_addr; // remote client address (zero for s2s connections)
 	void* session_data;
 	RecvFunc func_recv;
 	SendFunc func_send;
@@ -106,12 +106,12 @@ extern int session_isActive(int fd);
 
 // Function prototype declaration
 
-int make_listen_bind(long,int);
-int make_connection(long,int);
-int realloc_fifo(int fd,unsigned int rfifo_size,unsigned int wfifo_size);
+int make_listen_bind(uint32 ip, uint16 port);
+int make_connection(uint32 ip, uint16 port);
+int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
 int realloc_writefifo(int fd, size_t addition);
-int WFIFOSET(int fd,int len);
-int RFIFOSKIP(int fd,int len);
+int WFIFOSET(int fd, int len);
+int RFIFOSKIP(int fd, int len);
 
 int do_sendrecv(int next);
 int do_parsepacket(void);
@@ -126,9 +126,9 @@ extern void set_nonblocking(int fd, int yes);
 void set_defaultparse(ParseFunc defaultparse);
 
 // hostname/ip conversion functions
-in_addr_t host2ip(const char* hostname);
-const char* ip2str(in_addr_t ip, char ip_str[16]);
-
+uint32 host2ip(const char* hostname);
+const char* ip2str(uint32 ip, char ip_str[16]);
+#define CONVIP(ip) (ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,(ip>>0)&0xFF
 
 int socket_getips(uint32* ips, int max);
 

+ 25 - 21
src/common/strlib.c

@@ -11,12 +11,15 @@
 #include "../common/utils.h"
 #include "../common/malloc.h"
 
-//-----------------------------------------------
-// string lib.
-char* jstrescape (char* pt) {
+
+#define J_MAX_MALLOC_SIZE 65535
+
+// escapes a string in-place (' -> \' , \ -> \\ , % -> _)
+char* jstrescape (char* pt)
+{
 	//copy from here
 	char *ptr;
-	int i =0, j=0;
+	int i = 0, j = 0;
 
 	//copy string to temporary
 	CREATE(ptr, char, J_MAX_MALLOC_SIZE);
@@ -41,10 +44,12 @@ char* jstrescape (char* pt) {
 	}
 	pt[j++] = '\0';
 	aFree(ptr);
-	return &pt[0];
+	return pt;
 }
 
-char* jstrescapecpy (char* pt, const char* spt) {
+// escapes a string into a provided buffer
+char* jstrescapecpy (char* pt, const char* spt)
+{
 	//copy from here
 	//WARNING: Target string pt should be able to hold strlen(spt)*2, as each time
 	//a escape character is found, the target's final length increases! [Skotlex]
@@ -75,7 +80,10 @@ char* jstrescapecpy (char* pt, const char* spt) {
 	pt[j++] = '\0';
 	return &pt[0];
 }
-int jmemescapecpy (char* pt,char* spt, int size) {
+
+// escapes exactly 'size' bytes of a string into a provided buffer
+int jmemescapecpy (char* pt, const char* spt, int size)
+{
 	//copy from here
 	int i =0, j=0;
 
@@ -100,11 +108,9 @@ int jmemescapecpy (char* pt,char* spt, int size) {
 	return j;
 }
 
-//-----------------------------------------------------
 // Function to suppress control characters in a string.
-//-----------------------------------------------------
-//int remove_control_chars(char *str) {
-int remove_control_chars(unsigned char *str) {
+int remove_control_chars(char* str)
+{
 	int i;
 	int change = 0;
 
@@ -119,11 +125,11 @@ int remove_control_chars(unsigned char *str) {
 }
 
 //Trims a string, also removes illegal characters such as \t and reduces continous spaces to a single one. by [Foruken]
-char *trim(char *str, const char *delim)
+char* trim(char* str, const char* delim)
 {
-	char *strp = strtok(str,delim);
+	char* strp = strtok(str,delim);
 	char buf[1024];
-	char *bufp = buf;
+	char* bufp = buf;
 	memset(buf,0,sizeof buf);
 
 	while(strp) {
@@ -143,7 +149,7 @@ char *trim(char *str, const char *delim)
 //stristr: Case insensitive version of strstr, code taken from 
 //http://www.daniweb.com/code/snippet313.html, Dave Sinkula
 //
-const char *stristr(const char *haystack, const char *needle)
+const char* stristr(const char* haystack, const char* needle)
 {
 	if ( !*needle )
 	{
@@ -153,9 +159,7 @@ const char *stristr(const char *haystack, const char *needle)
 	{
 		if ( TOUPPER(*haystack) == TOUPPER(*needle) )
 		{
-			/*
-			* Matched starting char -- loop through remaining chars.
-			*/
+			// matched starting char -- loop through remaining chars
 			const char *h, *n;
 			for ( h = haystack, n = needle; *h && *n; ++h, ++n )
 			{
@@ -164,9 +168,9 @@ const char *stristr(const char *haystack, const char *needle)
 					break;
 				}
 			}
-			if ( !*n ) /* matched all of 'needle' to null termination */
+			if ( !*n ) // matched all of 'needle' to null termination
 			{
-				return haystack; /* return the start of the match */
+				return haystack; // return the start of the match
 			}
 		}
 	}
@@ -174,7 +178,7 @@ const char *stristr(const char *haystack, const char *needle)
 }
 
 #ifdef __WIN32
-char *_strtok_r(char *s1, const char *s2, char **lasts)
+char* _strtok_r(char *s1, const char *s2, char **lasts)
 {
 	char *ret;
 

+ 6 - 11
src/common/strlib.h

@@ -4,25 +4,20 @@
 #ifndef _STRLIB_H_
 #define _STRLIB_H_
 
-#define J_MAX_MALLOC_SIZE 65535
-// String function library.
-// code by Jioh L. Jung (ziozzang@4wish.net)
-// This code is under license "BSD"
 char* jstrescape (char* pt);
 char* jstrescapecpy (char* pt, const char* spt);
-int jmemescapecpy (char* pt,char* spt, int size);
+int jmemescapecpy (char* pt, const char* spt, int size);
+
+int remove_control_chars(char *);
+char *trim(char *str, const char *delim);
+const char *stristr(const char *haystack, const char *needle);
 
 #ifdef __WIN32
 #define HAVE_STRTOK_R
 #define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
-char *_strtok_r(char *s1, const char *s2, char **lasts);
+char* _strtok_r(char* s1, const char* s2, char** lasts);
 #endif
 
-// custom functions
-int remove_control_chars(unsigned char *);
-char *trim(char *str, const char *delim);
-const char *stristr(const char *haystack, const char *needle);
-
 #if !defined(WIN32) || (defined(_MSC_VER) && _MSC_VER < 1400)
 size_t strnlen (const char* string, size_t maxlen);
 #endif

+ 18 - 28
src/common/utils.c

@@ -20,28 +20,28 @@
 #include "../common/showmsg.h"
 #include "../common/cbasetypes.h"
 
-void dump(unsigned char *buffer, int num)
+void dump(unsigned char* buffer, int num)
 {
-   int     icnt,jcnt;
+   int icnt, jcnt;
 
    printf("         Hex                                                  ASCII\n");
    printf("         -----------------------------------------------      ----------------");
 
-   for (icnt=0;icnt<num;icnt+=16) {
-	printf("\n%p ",&buffer[icnt]);
-    for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
+   for (icnt = 0; icnt < num; icnt += 16) {
+	printf("\n%p ", &buffer[icnt]);
+    for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
 	    if (jcnt < num) {
-              printf("%02hX ",buffer[jcnt]);
+              printf("%02hX ", buffer[jcnt]);
 		}  else
               printf("   ");
     }
 
     printf("  |  ");
 
-	for (jcnt=icnt;jcnt<icnt+16;++jcnt) {
+	for (jcnt = icnt; jcnt < icnt + 16; ++jcnt) {
         if (jcnt < num) {
             if (buffer[jcnt] > 31 && buffer[jcnt] < 127)
-                   printf("%c",buffer[jcnt]);
+                   printf("%c", buffer[jcnt]);
                else
                    printf(".");
            }  else
@@ -266,30 +266,20 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
 
 unsigned char GetByte(unsigned long val, size_t num)
 {
-	switch(num)
-	{
-	case 0:
-		return (unsigned char)((val & 0x000000FF)      );
-	case 1:
-		return (unsigned char)((val & 0x0000FF00)>>0x08);
-	case 2:
-		return (unsigned char)((val & 0x00FF0000)>>0x10);
-	case 3:
-		return (unsigned char)((val & 0xFF000000)>>0x18);
-	default:
-		return 0;	//better throw something here
+	switch(num) {
+	case 0:  return (unsigned char)((val & 0x000000FF)      );
+	case 1:	 return (unsigned char)((val & 0x0000FF00)>>0x08);
+	case 2:	 return (unsigned char)((val & 0x00FF0000)>>0x10);
+	case 3:	 return (unsigned char)((val & 0xFF000000)>>0x18);
+	default: return 0;	//better throw something here
 	}
 }
 unsigned short GetWord(unsigned long val, size_t num)
 {
-	switch(num)
-	{
-	case 0:
-		return (unsigned short)((val & 0x0000FFFF)      );
-	case 1:
-		return (unsigned short)((val & 0xFFFF0000)>>0x10);
-	default:
-		return 0;	//better throw something here
+	switch(num) {
+	case 0:  return (unsigned short)((val & 0x0000FFFF)      );
+	case 1:  return (unsigned short)((val & 0xFFFF0000)>>0x10);
+	default: return 0;	//better throw something here
 	}
 }
 unsigned short MakeWord(unsigned char byte0, unsigned char byte1)

Разлика између датотеке није приказан због своје велике величине
+ 200 - 254
src/login/login.c


+ 180 - 181
src/login_sql/login.c

@@ -40,7 +40,7 @@
 
 struct Login_Config {
 
-	in_addr_t login_ip;								// the address to bind to
+	uint32 login_ip;								// the address to bind to
 	unsigned short login_port;						// the port to bind to
 	bool log_login;									// whether to log login server actions or not
 	char date_format[32];							// date format used in messages
@@ -71,17 +71,17 @@ struct mmo_char_server server[MAX_SERVERS]; // char server data
 
 // Advanced subnet check [LuzZza]
 struct _subnet {
-	long subnet;
-	long mask;
-	long char_ip;
-	long map_ip;
+	uint32 subnet;
+	uint32 mask;
+	uint32 char_ip;
+	uint32 map_ip;
 } subnet[16];
 
 int subnet_count = 0;
 
 
 struct gm_account* gm_account_db = NULL;
-int GM_num = 0; // number of gm accounts
+unsigned int GM_num = 0; // number of gm accounts
 
 //Account registration flood protection [Kevin]
 int allowed_regs = 1;
@@ -118,7 +118,9 @@ char login_db_level[256] = "level";
 #define AUTH_FIFO_SIZE 256
 struct {
 	int account_id,login_id1,login_id2;
-	int ip,sex,delflag;
+	uint32 ip;
+	char sex;
+	bool delflag;
 } auth_fifo[AUTH_FIFO_SIZE];
 
 int auth_fifo_pos = 0;
@@ -235,12 +237,13 @@ void read_gm_account(void)
 //-----------------------------------------------------
 void send_GM_accounts(int fd)
 {
-	int i;
+	unsigned int i;
 	unsigned char buf[32767];
 	int len;
 
 	if(!login_config.login_gm_read)
 		return;
+
 	len = 4;
 	WBUFW(buf,0) = 0x2732;
 	for(i = 0; i < GM_num; i++)
@@ -254,16 +257,17 @@ void send_GM_accounts(int fd)
 				break;
 			}
 		}
-		WBUFW(buf,2) = len;
-		if (fd == -1)
-			charif_sendallwos(-1, buf, len);
-		else
-		{
-			WFIFOHEAD(fd, len);
-			memcpy(WFIFOP(fd,0), buf, len);
-			WFIFOSET(fd, len);
-		}
-		return;
+
+	WBUFW(buf,2) = len;
+	if (fd == -1)
+		charif_sendallwos(-1, buf, len);
+	else
+	{
+		WFIFOHEAD(fd, len);
+		memcpy(WFIFOP(fd,0), buf, len);
+		WFIFOSET(fd, len);
+	}
+	return;
 }
 
 //---------------------------------------------------
@@ -497,20 +501,20 @@ int mmo_auth_new(struct mmo_account* account, char sex)
 	return 0;
 }
 
-// Send to char
+//--------------------------------------------------------------------
+// Packet send to all char-servers, except one (wos: without our self)
+//--------------------------------------------------------------------
 int charif_sendallwos(int sfd, unsigned char *buf, unsigned int len)
 {
-	int i, c;
-	int fd;
+	int i, c, fd;
 
-	c = 0;
-	for(i = 0; i < MAX_SERVERS; i++) {
+	for(i = 0, c = 0; i < MAX_SERVERS; i++) {
 		if ((fd = server_fd[i]) > 0 && fd != sfd) {
-			WFIFOHEAD(fd,len);
+			WFIFOHEAD(fd, len);
 			if (WFIFOSPACE(fd) < len) //Increase buffer size.
 				realloc_writefifo(fd, len);
 			memcpy(WFIFOP(fd,0), buf, len);
-			WFIFOSET(fd,len);
+			WFIFOSET(fd, len);
 			c++;
 		}
 	}
@@ -532,8 +536,9 @@ int mmo_auth(struct mmo_account* account, int fd)
 	char md5str[64], md5bin[32];
 
 	char ip[16];
-	unsigned char* sin_addr = (unsigned char *)&session[fd]->client_addr.sin_addr.s_addr;
-	sprintf(ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
+	uint32 ipl = session[fd]->client_addr;
+	uint8* sin_addr = (uint8*)&ipl;
+	sprintf(ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
 
 	// DNS Blacklist check
 	if(login_config.use_dnsbl)
@@ -543,7 +548,7 @@ int mmo_auth(struct mmo_account* account, int fd)
 		char *dnsbl_serv;
 		bool matched = false;
 
-		sprintf(r_ip, "%d.%d.%d.%d", sin_addr[3], sin_addr[2], sin_addr[1], sin_addr[0]);
+		sprintf(r_ip, "%d.%d.%d.%d", sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3]);
 
 		for (dnsbl_serv = strtok(login_config.dnsbl_servs,","); dnsbl_serv != NULL; dnsbl_serv = strtok(NULL,","))
 		{
@@ -720,9 +725,9 @@ int mmo_auth(struct mmo_account* account, int fd)
 
 	if (login_config.online_check) {
 		struct online_login_data* data = idb_get(online_db,account->account_id);
-		unsigned char buf[8];
 		if (data && data->char_server > -1) {
 			//Request char servers to kick this account out. [Skotlex]
+			unsigned char buf[8];
 			ShowNotice("User [%s] is already online - Rejected.\n",account->userid);
 			WBUFW(buf,0) = 0x2734;
 			WBUFL(buf,2) = account->account_id;
@@ -764,19 +769,18 @@ static int online_db_setoffline(DBKey key, void* data, va_list ap)
 	return 0;
 }
 
-//-----------------------------------------------------
-// char-server packet parse
-//-----------------------------------------------------
+//--------------------------------
+// Packet parsing for char-servers
+//--------------------------------
 int parse_fromchar(int fd)
 {
 	int i, id;
 
-	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
-	unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
+	uint32 ipl = session[fd]->client_addr;
 	char ip[16];
 	RFIFOHEAD(fd);
 
-	sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+	ip2str(ipl, ip);
 
 	for(id = 0; id < MAX_SERVERS; id++)
 		if (server_fd[id] == fd)
@@ -802,14 +806,14 @@ int parse_fromchar(int fd)
 		return 0;
 	}
 
-	while(RFIFOREST(fd) >= 2) {
-//		printf("char_parse: %d %d packet case=%x\n", fd, RFIFOREST(fd), RFIFOW(fd, 0));
+	while (RFIFOREST(fd) >= 2) {
 
 		switch (RFIFOW(fd,0)) {
-		case 0x2709:
+
+		case 0x2709: // request from map-server via char-server to reload GM accounts
 			if (login_config.log_login)
 			{
-				sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, (unsigned int)ntohl(ipl),server[id].name);
+				sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`log`) VALUES (NOW(), '%u', '%s', 'GM reload request')", loginlog_db, ipl, server[id].name);
 				if (mysql_query(&mysql_handle, tmpsql)) {
 					ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 					ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -821,7 +825,7 @@ int parse_fromchar(int fd)
 			RFIFOSKIP(fd,2);
 			break;
 
-		case 0x2712:
+		case 0x2712: // request from char-server to authenticate an account
 			if (RFIFOREST(fd) < 19)
 				return 0;
 		{
@@ -833,7 +837,7 @@ int parse_fromchar(int fd)
 				    auth_fifo[i].login_id1 == RFIFOL(fd,6) &&
 				    auth_fifo[i].login_id2 == RFIFOL(fd,10) && // relate to the versions higher than 18
 				    auth_fifo[i].sex == RFIFOB(fd,14) &&
-				    auth_fifo[i].ip == RFIFOL(fd,15) &&
+				    auth_fifo[i].ip == ntohl(RFIFOL(fd,15)) &&
 				    !auth_fifo[i].delflag)
 				{
 					auth_fifo[i].delflag = 1;
@@ -869,9 +873,10 @@ int parse_fromchar(int fd)
 				WFIFOB(fd,6) = 1;
 				WFIFOSET(fd,51);
 			}
+		}
 			RFIFOSKIP(fd,19);
 			break;
-		}
+		
 
 		case 0x2714:
 			if (RFIFOREST(fd) < 6)
@@ -897,8 +902,7 @@ int parse_fromchar(int fd)
 			RFIFOSKIP(fd,6);
 			break;
 
-		// We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server
-		case 0x2716:
+		case 0x2716: // received an e-mail/limited time request, because a player comes back from a map-server to the char-server
 			if (RFIFOREST(fd) < 6)
 				return 0;
 		{
@@ -929,10 +933,8 @@ int parse_fromchar(int fd)
 			RFIFOSKIP(fd,6);
 			break;
 
-		case 0x2720:	// GM
-			if (RFIFOREST(fd) < 4)
-				return 0;
-			if (RFIFOREST(fd) < RFIFOW(fd,2))
+		case 0x2720: // Request to become a GM (TXT only!)
+			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
 				return 0;
 			//oldacc = RFIFOL(fd,4);
 			ShowWarning("change GM isn't supported in this login server version.\n");
@@ -995,7 +997,7 @@ int parse_fromchar(int fd)
 			break;
 		}
 
-		case 0x2724:	// Receiving of map-server via char-server a status change resquest (by Yor)
+		case 0x2724: // Receiving of map-server via char-server a status change resquest
 			if (RFIFOREST(fd) < 10)
 				return 0;
 		{
@@ -1029,7 +1031,7 @@ int parse_fromchar(int fd)
 			break;
 		}
 
-		case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor)
+		case 0x2725: // Receiving of map-server via char-server a ban resquest
 			if (RFIFOREST(fd) < 18)
 				return 0;
 		{
@@ -1084,7 +1086,7 @@ int parse_fromchar(int fd)
 			break;
 		}
 
-		case 0x2727:
+		case 0x2727: // Change of sex (sex is reversed)
 			if (RFIFOREST(fd) < 6)
 				return 0;
 		{
@@ -1168,10 +1170,9 @@ int parse_fromchar(int fd)
 				if (buf) aFree(buf);
 			}
 			RFIFOSKIP(fd,RFIFOW(fd,2));
-			//printf("login: save account_reg (from char)\n");
 			break;
 
-		case 0x272a:	// Receiving of map-server via char-server a unban resquest (by Yor)
+		case 0x272a:	// Receiving of map-server via char-server a unban resquest
 			if (RFIFOREST(fd) < 6)
 				return 0;
 			{
@@ -1209,6 +1210,7 @@ int parse_fromchar(int fd)
 			remove_online_user(RFIFOL(fd,2));
 			RFIFOSKIP(fd,6);
 			break;
+
 		case 0x272d:	// Receive list of all online accounts. [Skotlex]
 			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
 				return 0;
@@ -1270,10 +1272,8 @@ int parse_fromchar(int fd)
 		case 0x2736: // WAN IP update from char-server
 			if (RFIFOREST(fd) < 6)
 				return 0;
-			ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id,
-			(int)RFIFOB(fd,2),(int)RFIFOB(fd,3),
-			(int)RFIFOB(fd,4),(int)RFIFOB(fd,5));
-			server[id].ip = RFIFOL(fd,2);
+			server[id].ip = ntohl(RFIFOL(fd,2));
+			ShowInfo("Updated IP of Server #%d to %d.%d.%d.%d.\n",id, CONVIP(server[id].ip));
 			RFIFOSKIP(fd,6);
 			break;
 
@@ -1284,7 +1284,7 @@ int parse_fromchar(int fd)
 			break;
 
 		default:
-			ShowError("login: unknown packet %x! (from char).\n", RFIFOW(fd,0));
+			ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", RFIFOW(fd,0));
 			session[fd]->eof = 1;
 			return 0;
 		}
@@ -1297,12 +1297,12 @@ int parse_fromchar(int fd)
 //--------------------------------------------
 // Test to know if an IP come from LAN or WAN.
 //--------------------------------------------
-int lan_subnetcheck(long p)
+int lan_subnetcheck(uint32 ip)
 {
 	int i;
 
-	for(i=0; i<subnet_count; i++) {
-		if(subnet[i].subnet == (p & subnet[i].mask)) {
+	for(i = 0; i < subnet_count; i++) {
+		if(subnet[i].subnet == (ip & subnet[i].mask)) {
 			return subnet[i].char_ip;
 		}
 	}
@@ -1310,14 +1310,11 @@ int lan_subnetcheck(long p)
 	return 0;
 }
 
-int login_ip_ban_check(unsigned char *p, unsigned long ipl)
+int login_ip_ban_check(uint32 ip)
 {
-	//ip ban
-	//p[0], p[1], p[2], p[3]
-	//request DB connection
-	//check
+	char* p = (char*)&ip;
 	sprintf(tmpsql, "SELECT count(*) FROM `ipbanlist` WHERE `list` = '%d.*.*.*' OR `list` = '%d.%d.*.*' OR `list` = '%d.%d.%d.*' OR `list` = '%d.%d.%d.%d'",
-		p[0], p[0], p[1], p[0], p[1], p[2], p[0], p[1], p[2], p[3]);
+		p[3], p[3], p[2], p[3], p[2], p[1], p[3], p[2], p[1], p[0]);
 	if (mysql_query(&mysql_handle, tmpsql)) {
 		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1338,11 +1335,11 @@ int login_ip_ban_check(unsigned char *p, unsigned long ipl)
 	}
 		
 	// ip ban ok.
-	ShowInfo("Packet from banned ip : %d.%d.%d.%d\n" RETCODE, p[0], p[1], p[2], p[3]);
+	ShowInfo("Packet from banned ip : %d.%d.%d.%d\n" RETCODE, CONVIP(ip));
 
 	if (login_config.log_login)
 	{
-		sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', 'unknown','-3', 'ip banned')", loginlog_db, (unsigned int)ntohl(ipl));
+		sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', 'unknown','-3', 'ip banned')", loginlog_db, ip);
 		// query
 		if(mysql_query(&mysql_handle, tmpsql)) {
 			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
@@ -1360,16 +1357,13 @@ int parse_login(int fd)
 {
 	char t_uid[100];
 	struct mmo_account account;
-	long subnet_char_ip;
-	int packet_len;
 
 	int result, i;
-	unsigned char *p = (unsigned char *) &session[fd]->client_addr.sin_addr.s_addr;
-	unsigned long ipl = session[fd]->client_addr.sin_addr.s_addr;
+	uint32 ipl = session[fd]->client_addr;
 	char ip[16];
 	RFIFOHEAD(fd);
 
-	sprintf(ip, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+	ip2str(ipl, ip);
 
 	memset(&account, 0, sizeof(account));
 
@@ -1381,9 +1375,9 @@ int parse_login(int fd)
 		return 0;
 	}
 
-	while(RFIFOREST(fd)>=2 && !session[fd]->eof){
+	while(RFIFOREST(fd) >= 2) {
 
-		switch(RFIFOW(fd,0)){
+		switch(RFIFOW(fd,0)) {
 		case 0x200:		// New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive.
 			if (RFIFOREST(fd) < 26)
 				return 0;
@@ -1399,18 +1393,22 @@ int parse_login(int fd)
 		case 0x277:		// New login packet
 		case 0x64:		// request client login
 		case 0x01dd:	// request client login with encrypt
+		{
+			int packet_len = RFIFOREST(fd);
 
-			packet_len = RFIFOREST(fd);
-
-			//Perform ip-ban check ONLY on login packets
-			if (login_config.ipban && login_ip_ban_check(p,ipl))
+			//Perform ip-ban check
+			if (login_config.ipban && login_ip_ban_check(ipl))
 			{
+				WFIFOHEAD(fd, 23);
+				WFIFOW(fd,0) = 0x6a;
+				WFIFOB(fd,2) = 3; // 3 = Rejected from Server
+				WFIFOSET(fd,23);
 				RFIFOSKIP(fd,packet_len);
 				session[fd]->eof = 1;
 				break;
 			}
 
-			switch(RFIFOW(fd,0)){
+			switch(RFIFOW(fd, 0)){
 				case 0x64:
 					if(packet_len < 55)
 						return 0;
@@ -1432,7 +1430,6 @@ int parse_login(int fd)
 			memcpy(account.passwd,RFIFOP(fd, 30),NAME_LENGTH);
 			account.passwd[23] = '\0';
 
-//			ShowDebug("client connection request %s from %d.%d.%d.%d\n", RFIFOP(fd, 6), p[0], p[1], p[2], p[3]);
 #ifdef PASSWORDENC
 			account.passwdenc= (RFIFOW(fd,0)!=0x01dd)?0:PASSWORDENC;
 #else
@@ -1441,7 +1438,7 @@ int parse_login(int fd)
 			result=mmo_auth(&account, fd);
 
 			jstrescapecpy(t_uid,account.userid);
-			if(result==-1){
+			if(result==-1) {  // auth success
 				if (login_config.min_level_to_connect > account.level) {
 					WFIFOHEAD(fd,3);
 					WFIFOW(fd,0) = 0x81;
@@ -1449,8 +1446,8 @@ int parse_login(int fd)
 					WFIFOSET(fd,3);
 				} else {
 					WFIFOHEAD(fd,47+32*MAX_SERVERS);
-					if (p[0] != 127 && login_config.log_login) {
-						sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, (unsigned int)ntohl(ipl), t_uid);
+					if (login_config.log_login) {
+						sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s','100', 'login ok')", loginlog_db, ipl, t_uid);
 						//query
 						if(mysql_query(&mysql_handle, tmpsql)) {
 							ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
@@ -1461,15 +1458,14 @@ int parse_login(int fd)
 						ShowStatus("Connection of the GM (level:%d) account '%s' accepted.\n", account.level, account.userid);
 					else
 						ShowStatus("Connection of the account '%s' accepted.\n", account.userid);
-					server_num=0;
+
+					server_num = 0;
 					for(i = 0; i < MAX_SERVERS; i++) {
 						if (server_fd[i] >= 0) {
 							// Advanced subnet check [LuzZza]
-							if((subnet_char_ip = lan_subnetcheck(ipl)))
-								WFIFOL(fd,47+server_num*32) = subnet_char_ip;
-							else
-								WFIFOL(fd,47+server_num*32) = server[i].ip;
-							WFIFOW(fd,47+server_num*32+4) = server[i].port;
+							uint32 subnet_char_ip = lan_subnetcheck(ipl);
+							WFIFOL(fd,47+server_num*32) = (subnet_char_ip) ? htonl(subnet_char_ip) : htonl(server[i].ip);
+							WFIFOW(fd,47+server_num*32+4) = server[i].port; // /!\ must be sent in intel host byte order /!\ (client bug)
 							memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
 							WFIFOW(fd,47+server_num*32+26) = server[i].users;
 							WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
@@ -1477,34 +1473,33 @@ int parse_login(int fd)
 							server_num++;
 						}
 					}
-					// if at least 1 char-server
-					if (server_num > 0) {
-						WFIFOW(fd,0)=0x69;
-						WFIFOW(fd,2)=47+32*server_num;
-						WFIFOL(fd,4)=account.login_id1;
-						WFIFOL(fd,8)=account.account_id;
-						WFIFOL(fd,12)=account.login_id2;
-						WFIFOL(fd,16)=0;
-						//memcpy(WFIFOP(fd,20),account.lastlogin,24);
-						WFIFOB(fd,46)=account.sex;
+					if (server_num > 0) { // if at least 1 char-server
+						WFIFOW(fd,0) = 0x69;
+						WFIFOW(fd,2) = 47+32*server_num;
+						WFIFOL(fd,4) = account.login_id1;
+						WFIFOL(fd,8) = account.account_id;
+						WFIFOL(fd,12) = account.login_id2;
+						WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used)
+						//memcpy(WFIFOP(fd,20), account.lastlogin, 24); // in old version, that was for name (not more used)
+						WFIFOB(fd,46) = account.sex;
 						WFIFOSET(fd,47+32*server_num);
-						if(auth_fifo_pos>=AUTH_FIFO_SIZE)
-							auth_fifo_pos=0;
-						auth_fifo[auth_fifo_pos].account_id=account.account_id;
-						auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
-						auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
-						auth_fifo[auth_fifo_pos].sex=account.sex;
-						auth_fifo[auth_fifo_pos].delflag=0;
-						auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr.sin_addr.s_addr;
+						if (auth_fifo_pos >= AUTH_FIFO_SIZE)
+							auth_fifo_pos = 0;
+						auth_fifo[auth_fifo_pos].account_id = account.account_id;
+						auth_fifo[auth_fifo_pos].login_id1 = account.login_id1;
+						auth_fifo[auth_fifo_pos].login_id2 = account.login_id2;
+						auth_fifo[auth_fifo_pos].sex = account.sex;
+						auth_fifo[auth_fifo_pos].delflag = 0;
+						auth_fifo[auth_fifo_pos].ip = session[fd]->client_addr;
 						auth_fifo_pos++;
-					} else {
+					} else { // if no char-server, don't send void list of servers, just disconnect the player with proper message
 						WFIFOW(fd,0) = 0x81;
 						WFIFOB(fd,2) = 1; // 01 = Server closed
 						WFIFOSET(fd,3);
 					}
 				}
-			} else {
-				WFIFOHEAD(fd,23);
+			} else { // auth failed
+				WFIFOHEAD(fd, 23);
 				if (login_config.log_login)
 				{
 					const char* error;
@@ -1536,7 +1531,7 @@ int parse_login(int fd)
 					default : error = "Unknown Error."; break;
 					}
 
-					sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %s')", loginlog_db, (unsigned int)ntohl(ipl), t_uid, result, error);
+					sprintf(tmpsql, "INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s', '%d','login failed : %s')", loginlog_db, ipl, t_uid, result, error);
 
 					//query
 					if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1547,7 +1542,7 @@ int parse_login(int fd)
 
 				if ((result == 1) && login_config.dynamic_pass_failure_ban && login_config.log_login) {	// failed password
 					sprintf(tmpsql,"SELECT count(*) FROM `%s` WHERE `ip` = '%u' AND `rcode` = '1' AND `time` > NOW() - INTERVAL %d MINUTE",
-						loginlog_db,(unsigned int)ntohl(ipl), login_config.dynamic_pass_failure_ban_interval);	//how many times filed account? in one ip.
+						loginlog_db, ipl, login_config.dynamic_pass_failure_ban_interval); //how many times filed account? in one ip.
 					if(mysql_query(&mysql_handle, tmpsql)) {
 						ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1557,7 +1552,8 @@ int parse_login(int fd)
 					sql_row = sql_res?mysql_fetch_row(sql_res):NULL;	//row fetching
 
 					if (sql_row && (unsigned int)atoi(sql_row[0]) >= login_config.dynamic_pass_failure_ban_limit ) {
-						sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() +  INTERVAL %d MINUTE ,'Password error ban: %s')", p[0], p[1], p[2], login_config.dynamic_pass_failure_ban_duration, t_uid);
+						uint8* p = (uint8*)&ipl;
+						sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() +  INTERVAL %d MINUTE ,'Password error ban: %s')", (uint8)p[3], (uint8)p[2], (uint8)p[1], login_config.dynamic_pass_failure_ban_duration, t_uid);
 						if(mysql_query(&mysql_handle, tmpsql)) {
 							ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 							ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1566,7 +1562,8 @@ int parse_login(int fd)
 					if(sql_res) mysql_free_result(sql_res);
 				}
 				else if (result == -2){	//dynamic banned - add ip to ban list.
-					sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() +  INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", p[0], p[1], p[2], t_uid);
+					uint8* p = (uint8*)&ipl;
+					sprintf(tmpsql,"INSERT INTO `ipbanlist`(`list`,`btime`,`rtime`,`reason`) VALUES ('%d.%d.%d.*', NOW() , NOW() +  INTERVAL 1 MONTH ,'Dynamic banned user id : %s')", (uint8)p[3], (uint8)p[2], (uint8)p[1], t_uid);
 					if(mysql_query(&mysql_handle, tmpsql)) {
 						ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
@@ -1583,21 +1580,24 @@ int parse_login(int fd)
 				}
 				sql_res = mysql_store_result(&mysql_handle) ;
 				sql_row = sql_res?mysql_fetch_row(sql_res):NULL;
+
 				//cannot connect login failed
-				memset(WFIFOP(fd,0),'\0',23);
-				WFIFOW(fd,0)=0x6a;
-				WFIFOB(fd,2)=result;
+				memset(WFIFOP(fd,0), '\0', 23);
+				WFIFOW(fd,0) = 0x6a;
+				WFIFOB(fd,2) = result;
 				if (result == 6) { // 6 = Your are Prohibited to log in until %s
 					char tmpstr[20];
 					time_t ban_until_time = (sql_row) ? atol(sql_row[0]) : 0;
-					strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time));
-					tmpstr[19] = '\0';
+					strftime(tmpstr, 20, login_config.date_format, localtime(&ban_until_time)); tmpstr[19] = '\0';
 					strncpy(WFIFOP(fd,3), tmpstr, 20); // ban timestamp goes here
 				}
 				WFIFOSET(fd,23);
+
+				if (sql_res) mysql_free_result(sql_res);
 			}
 			RFIFOSKIP(fd,packet_len);
 			break;
+		}
 
 		case 0x01db:	// request password key
 			if (session[fd]->session_data) {
@@ -1606,41 +1606,39 @@ int parse_login(int fd)
 				return 0;
 			}
 		{
-			WFIFOHEAD(fd,4+md5keylen);
-			WFIFOW(fd,0)=0x01dc;
-			WFIFOW(fd,2)=4+md5keylen;
-			memcpy(WFIFOP(fd,4),md5key,md5keylen);
-			WFIFOSET(fd,WFIFOW(fd,2));
 			RFIFOSKIP(fd,2);
+			WFIFOHEAD(fd, 4 + md5keylen);
+			WFIFOW(fd,0) = 0x01dc;
+			WFIFOW(fd,2) = 4 + md5keylen;
+			memcpy(WFIFOP(fd,4), md5key, md5keylen);
+			WFIFOSET(fd,WFIFOW(fd,2));
 		}
 			break;
 
-		case 0x2710:	// request Char-server connection
-			if(RFIFOREST(fd)<86)
+		case 0x2710:	// Connection request of a char-server
+			if (RFIFOREST(fd) < 86)
 				return 0;
 			{
 				char* server_name;
+				uint32 server_ip;
+				uint16 server_port;
+
 				WFIFOHEAD(fd, 3);
-				memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH);
-				account.userid[23] = '\0';
-				memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH);
-				account.passwd[23] = '\0';
+				memcpy(account.userid,RFIFOP(fd, 2),NAME_LENGTH); account.userid[23] = '\0';
+				memcpy(account.passwd,RFIFOP(fd, 26),NAME_LENGTH); account.passwd[23] = '\0';
 				account.passwdenc = 0;
-				server_name = (char*)RFIFOP(fd,60);
-				server_name[20] = '\0';
-				ShowInfo("server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)\n",
-					server_name, RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57), RFIFOW(fd, 58),
-					p[0], p[1], p[2], p[3]);
-				jstrescapecpy(t_uid,server_name);
+				server_name = (char*)RFIFOP(fd,60); server_name[20] = '\0';
+				server_ip = ntohl(RFIFOL(fd, 54));
+				server_port = ntohs(RFIFOW(fd, 58));
+				ShowInfo("Connection request of the char-server '%s' @ %d.%d.%d.%d:%d (ip: %s)\n",
+					server_name, CONVIP(server_ip), server_port, ip);
+				jstrescapecpy(t_uid, server_name);
 				if (login_config.log_login)
 				{
 					char t_login[50];
 					jstrescapecpy(t_login,account.userid);
 					sprintf(tmpsql,"INSERT DELAYED INTO `%s`(`time`,`ip`,`user`,`rcode`,`log`) VALUES (NOW(), '%u', '%s@%s','100', 'charserver - %s@%d.%d.%d.%d:%d')",
-						loginlog_db, (unsigned int)ntohl(ipl),
-						t_login, t_uid, t_uid,
-						RFIFOB(fd, 54), RFIFOB(fd, 55), RFIFOB(fd, 56), RFIFOB(fd, 57),
-						RFIFOW(fd, 58));
+						loginlog_db, ipl, t_login, t_uid, t_uid, CONVIP(server_ip), server_port);
 
 					//query
 					if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1648,19 +1646,18 @@ int parse_login(int fd)
 						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
 					}
 				}
-				result = mmo_auth(&account, fd);
-				//printf("Result: %d - Sex: %d - Account ID: %d\n",result,account.sex,(int) account.account_id);
 
-				if(result == -1 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]==-1){
+				result = mmo_auth(&account, fd);
+				if (result == -1 && account.sex == 2 && account.account_id < MAX_SERVERS && server_fd[account.account_id] == -1) {
 					ShowStatus("Connection of the char-server '%s' accepted.\n", server_name);
 					memset(&server[account.account_id], 0, sizeof(struct mmo_char_server));
-					server[account.account_id].ip=RFIFOL(fd,54);
-					server[account.account_id].port=RFIFOW(fd,58);
-					memcpy(server[account.account_id].name,server_name,20);
-					server[account.account_id].users=0;
-					server[account.account_id].maintenance=RFIFOW(fd,82);
-					server[account.account_id].new_=RFIFOW(fd,84);
-					server_fd[account.account_id]=fd;
+					server[account.account_id].ip = ntohl(RFIFOL(fd,54));
+					server[account.account_id].port = ntohs(RFIFOW(fd,58));
+					memcpy(server[account.account_id].name, server_name, 20);
+					server[account.account_id].users = 0;
+					server[account.account_id].maintenance = RFIFOW(fd,82);
+					server[account.account_id].new_ = RFIFOW(fd,84);
+					server_fd[account.account_id] = fd;
 					sprintf(tmpsql,"DELETE FROM `sstatus` WHERE `index`='%d'", account.account_id);
 					//query
 					if(mysql_query(&mysql_handle, tmpsql)) {
@@ -1675,42 +1672,43 @@ int parse_login(int fd)
 						ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
 						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmpsql);
 					}
-					WFIFOW(fd,0)=0x2711;
-					WFIFOB(fd,2)=0;
+					WFIFOW(fd,0) = 0x2711;
+					WFIFOB(fd,2) = 0;
 					WFIFOSET(fd,3);
-					session[fd]->func_parse=parse_fromchar;
-					realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
+					session[fd]->func_parse = parse_fromchar;
+					realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
 					// send GM account to char-server
 					send_GM_accounts(fd);
 				} else {
-					WFIFOW(fd, 0) =0x2711;
-					WFIFOB(fd, 2)=3;
-					WFIFOSET(fd, 3);
+					WFIFOW(fd,0) = 0x2711;
+					WFIFOB(fd,2) = 3;
+					WFIFOSET(fd,3);
 				}
 			}
-			RFIFOSKIP(fd, 86);
+			RFIFOSKIP(fd,86);
 			return 0;
 
 		case 0x7530:	// request Athena information
 		{
+			ShowInfo ("Athena version check...\n");
 			WFIFOHEAD(fd,10);
-			WFIFOW(fd,0)=0x7531;
-			WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
-			WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
-			WFIFOB(fd,4)=ATHENA_REVISION;
-			WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
-			WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
-			WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
-			WFIFOW(fd,8)=ATHENA_MOD_VERSION;
+			WFIFOW(fd,0) = 0x7531;
+			WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
+			WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
+			WFIFOB(fd,4) = ATHENA_REVISION;
+			WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
+			WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
+			WFIFOB(fd,7) = ATHENA_SERVER_LOGIN;
+			WFIFOW(fd,8) = ATHENA_MOD_VERSION;
 			WFIFOSET(fd,10);
 			RFIFOSKIP(fd,2);
-			ShowInfo ("Athena version check...\n");
 			break;
 		}
-		case 0x7532:
+		case 0x7532:	// Request to end connection
 			ShowStatus ("End of connection (ip: %s)" RETCODE, ip);
 			session[fd]->eof = 1;
 			break;
+
 		default:
 			ShowStatus ("Abnormal end of connection (ip: %s): Unknown packet 0x%x " RETCODE, ip, RFIFOW(fd,0));
 			session[fd]->eof = 1;
@@ -1782,7 +1780,6 @@ int config_switch(const char *str)
 	return atoi(str);
 }
 
-
 //----------------------------------
 // Reading Lan Support configuration
 //----------------------------------
@@ -1805,7 +1802,7 @@ int login_lan_config_read(const char *lancfgName)
 		if ((line[0] == '/' && line[1] == '/') || line[0] == '\n' || line[1] == '\n')
 			continue;
 
-		line[sizeof(line)-1] = '\0';
+		line[sizeof(line)-1] = '\0';	
 		if(sscanf(line,"%[^:]: %[^:]:%[^:]:%[^\r\n]", w1, w2, w3, w4) != 4) {
 
 			ShowWarning("Error syntax of configuration file %s in line %d.\n", lancfgName, line_num);	
@@ -1819,9 +1816,9 @@ int login_lan_config_read(const char *lancfgName)
 
 		if(strcmpi(w1, "subnet") == 0) {
 
-			subnet[subnet_count].mask = inet_addr(w2);
-			subnet[subnet_count].char_ip = inet_addr(w3);
-			subnet[subnet_count].map_ip = inet_addr(w4);
+			subnet[subnet_count].mask = ntohl(inet_addr(w2));
+			subnet[subnet_count].char_ip = ntohl(inet_addr(w3));
+			subnet[subnet_count].map_ip = ntohl(inet_addr(w4));
 			subnet[subnet_count].subnet = subnet[subnet_count].char_ip&subnet[subnet_count].mask;
 			if (subnet[subnet_count].subnet != (subnet[subnet_count].map_ip&subnet[subnet_count].mask)) {
 				ShowError("%s: Configuration Error: The char server (%s) and map server (%s) belong to different subnetworks!\n", lancfgName, w3, w4);
@@ -1851,9 +1848,9 @@ int ip_ban_flush(int tid, unsigned int tick, int id, int data)
 	return 0;
 }
 
-//-----------------------------------------------------
+//-----------------------------------
 // Reading main configuration file
-//-----------------------------------------------------
+//-----------------------------------
 int login_config_read(const char* cfgName)
 {
 	char line[1024], w1[1024], w2[1024];
@@ -1867,11 +1864,12 @@ int login_config_read(const char* cfgName)
 	{
 		if (line[0] == '/' && line[1] == '/')
 			continue;
+
 		if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) < 2)
 			continue;
 
-		remove_control_chars((unsigned char *) w1);
-		remove_control_chars((unsigned char *) w2);
+		remove_control_chars((unsigned char *)w1);
+		remove_control_chars((unsigned char *)w2);
 
 		if(!strcmpi(w1,"timestamp_format")) {
 			strncpy(timestamp_format, w2, 20);
@@ -1890,6 +1888,9 @@ int login_config_read(const char* cfgName)
 			login_config.login_port = (unsigned short)atoi(w2);
 			ShowStatus("set login_port : %s\n",w2);
 		}
+		else if (!strcmpi(w1, "log_login"))
+			login_config.log_login = config_switch(w2);
+
 		else if (!strcmpi(w1,"ipban"))
 			login_config.ipban = config_switch(w2);
 		else if (!strcmpi(w1,"dynamic_pass_failure_ban"))
@@ -1923,8 +1924,6 @@ int login_config_read(const char* cfgName)
 			time_allowed = atoi(w2);
 		else if (!strcmpi(w1, "online_check"))
 			login_config.online_check = config_switch(w2);
-		else if (!strcmpi(w1, "log_login"))
-			login_config.log_login = config_switch(w2);
 		else if (!strcmpi(w1,"use_dnsbl"))
 			login_config.use_dnsbl = config_switch(w2);
 		else if (!strcmpi(w1,"dnsbl_servers"))

+ 2 - 2
src/login_sql/login.h

@@ -42,8 +42,8 @@ struct mmo_account {
 
 struct mmo_char_server {
 	char name[20];
-	long ip;
-	short port;
+	uint32 ip;
+	uint16 port;
 	int users;
 	int maintenance;
 	int new_;

+ 54 - 93
src/map/chrif.c

@@ -24,18 +24,14 @@
 #include "status.h"
 #include "mercenary.h"
 
-//Updated table (only doc^^) [Sirius]
-//Used Packets: U->2af8
-//Free Packets: F->2af8
-
 struct dbt *auth_db;
 
-static const int packet_len_table[0x3d] = {
+static const int packet_len_table[0x3d] = { // U - used, F - free
 	60, 3,-1,27,10,-1, 6,-1,	// 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
 	 6,-1,18, 7,-1,49,30,10,	// 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
 	 6,30,-1,10,86, 7,44,34,	// 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
 	 0,-1,10, 6,11,-1, 0, 0,	// 2b10-2b17: U->2b10, U->2b11, U->2b12, U->2b13, U->2b14, U->2b15, U->2b16, U->2b17
-	-1,-1,-1,-1,-1,-1, 2, 7,		// 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
+	-1,-1,-1,-1,-1,-1, 2, 7,	// 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
 	-1,10, 8,-1,-1,-1,-1,-1,	// 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, F->2b24, F->2b25, F->2b26, F->2b27
 };
 
@@ -89,8 +85,8 @@ int chrif_connected = 0;
 int char_fd = 0; //Using 0 instead of -1 is safer against crashes. [Skotlex]
 int srvinfo;
 static char char_ip_str[128];
-static in_addr_t char_ip= 0;
-static int char_port = 6121;
+static uint32 char_ip = 0;
+static uint16 char_port = 6121;
 static char userid[NAME_LENGTH], passwd[NAME_LENGTH];
 static int chrif_state = 0;
 static int char_init_done = 0;
@@ -103,29 +99,20 @@ int other_mapserver_count=0; //Holds count of how many other map servers are onl
 //This define should spare writing the check in every function. [Skotlex]
 #define chrif_check(a) { if(!chrif_isconnect()) return a; }
 
-// 設定ファイル読み込み関係
-/*==========================================
- *
- *------------------------------------------
- */
+
+// sets char-server's user id
 void chrif_setuserid(char *id)
 {
 	memcpy(userid, id, NAME_LENGTH);
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
+// sets char-server's password
 void chrif_setpasswd(char *pwd)
 {
 	memcpy(passwd, pwd, NAME_LENGTH);
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
+// security check, prints warning if using default password
 void chrif_checkdefaultlogin(void)
 {
 	if (strcmp(userid, "s1")==0 && strcmp(passwd, "p1")==0) {
@@ -139,11 +126,8 @@ void chrif_checkdefaultlogin(void)
 	}
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
-int chrif_setip(const char *ip)
+// sets char-server's ip address
+int chrif_setip(const char* ip)
 {
 	char ip_str[16];
 	char_ip = host2ip(ip);
@@ -156,30 +140,23 @@ int chrif_setip(const char *ip)
 	return 1;
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
-void chrif_setport(int port)
+// sets char-server's port number
+void chrif_setport(uint16 port)
 {
 	char_port = port;
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
+// says whether the char-server is connected or not
 int chrif_isconnect(void)
 {
 	return (char_fd > 0 && session[char_fd] != NULL && chrif_state == 2);
 }
 
 /*==========================================
- * Saves char.
- * Flag = 1: Character is quitting.
+ * Saves character data.
+ * Flag = 1: Character is quitting
  * Flag = 2: Character is changing map-servers
- *------------------------------------------
- */
+ *------------------------------------------*/
 int chrif_save(struct map_session_data *sd, int flag)
 {
 	nullpo_retr(-1, sd);
@@ -226,10 +203,7 @@ int chrif_save(struct map_session_data *sd, int flag)
 	return 0;
 }
 
-/*==========================================
- *
- *------------------------------------------
- */
+// connects to char-server (plaintext)
 int chrif_connect(int fd)
 {
 	ShowStatus("Logging in to char server...\n", char_fd);
@@ -238,17 +212,14 @@ int chrif_connect(int fd)
 	memcpy(WFIFOP(fd,2), userid, NAME_LENGTH);
 	memcpy(WFIFOP(fd,26), passwd, NAME_LENGTH);
 	WFIFOL(fd,50) = 0;
-	WFIFOL(fd,54) = clif_getip_long();
-	WFIFOW(fd,58) = clif_getport();	// [Valaris] thanks to fov
+	WFIFOL(fd,54) = htonl(clif_getip());
+	WFIFOW(fd,58) = htons(clif_getport());
 	WFIFOSET(fd,60);
 
 	return 0;
 }
 
-/*==========================================
- * マップ送信
- *------------------------------------------
- */
+// sends maps to char-server
 int chrif_sendmap(int fd)
 {
 	int i;
@@ -263,36 +234,31 @@ int chrif_sendmap(int fd)
 	return 0;
 }
 
-/*==========================================
- * マップ受信
- *------------------------------------------
- */
+// receive maps from some other map-server (relayed via char-server)
 int chrif_recvmap(int fd)
 {
-	int i, j, ip, port;
-	unsigned char *p = (unsigned char *)&ip;
+	int i, j;
+	uint32 ip;
+	uint16 port;
 	RFIFOHEAD(fd);
-	ip = RFIFOL(fd,4);
-	port = RFIFOW(fd,8);
+	ip = ntohl(RFIFOL(fd,4));
+	port = ntohs(RFIFOW(fd,8));
 	for(i = 10, j = 0; i < RFIFOW(fd,2); i += 4, j++) {
 		map_setipport(RFIFOW(fd,i), ip, port);
-//		if (battle_config.etc_log)
-//			printf("recv map %d %s\n", j, RFIFOP(fd,i));
 	}
 	if (battle_config.etc_log)
-		ShowStatus("recv map on %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j);
+		ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
 
 	other_mapserver_count++;
 	return 0;
 }
 
-/*==========================================
- * Delete maps of other servers, (if an other mapserver is going OFF)
- *------------------------------------------
- */
-int chrif_removemap(int fd){
-	int i, j, ip, port;
-	unsigned char *p = (unsigned char *)&ip;
+// remove specified maps (used when some other map-server disconnects)
+int chrif_removemap(int fd)
+{
+	int i, j;
+	uint32 ip;
+	uint16 port;
 	RFIFOHEAD(fd);
 
 	ip = RFIFOL(fd, 4);
@@ -304,11 +270,13 @@ int chrif_removemap(int fd){
 
 	other_mapserver_count--;
 	if(battle_config.etc_log)
-		ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", p[0], p[1], p[2], p[3], port, j);
+		ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
 	return 0;
 }
 
-int chrif_save_ack(int fd) {
+// received after a character has been "final saved" on the char-server
+int chrif_save_ack(int fd)
+{
 	struct map_session_data *sd;
 	RFIFOHEAD(fd);
 	sd = map_id2sd(RFIFOL(fd,2));
@@ -318,13 +286,10 @@ int chrif_save_ack(int fd) {
 	return 0;
 }
 
-/*==========================================
- * マップ鯖間移動のためのデータ準備要求
- *------------------------------------------
- */
-int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, int ip, short port)
+// request to move a character between mapservers
+int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, uint32 ip, uint16 port)
 {
-	int s_ip;
+	uint32 s_ip;
 
 	nullpo_retr(-1, sd);
 
@@ -337,7 +302,7 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
 	}
 
 	if (sd->fd && sd->fd < fd_max && session[sd->fd])
-		s_ip = session[sd->fd]->client_addr.sin_addr.s_addr;
+		s_ip = session[sd->fd]->client_addr;
 	else //Not connected? Can't retrieve IP
 		s_ip = 0;
 
@@ -350,19 +315,16 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
 	WFIFOW(char_fd,18) = map;
 	WFIFOW(char_fd,20) = x;
 	WFIFOW(char_fd,22) = y;
-	WFIFOL(char_fd,24) = ip;
-	WFIFOW(char_fd,28) = port;
+	WFIFOL(char_fd,24) = htonl(ip);
+	WFIFOW(char_fd,28) = htons(port);
 	WFIFOB(char_fd,30) = sd->status.sex;
-	WFIFOL(char_fd,31) = s_ip;
+	WFIFOL(char_fd,31) = htonl(s_ip); // not used
 	WFIFOSET(char_fd,35);
 
 	return 0;
 }
 
-/*==========================================
- * マップ鯖間移動ack
- *------------------------------------------
- */
+// map-server change request acknowledgement (positive or negative)
 int chrif_changemapserverack(int fd)
 {
 	struct map_session_data *sd;
@@ -380,7 +342,7 @@ int chrif_changemapserverack(int fd)
 		return 0;
 	}
 	sprintf(mapname, "%s.gat", mapindex_id2name(RFIFOW(fd,18)));
-	clif_changemapserver(sd, mapname, RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28));
+	clif_changemapserver(sd, mapname, RFIFOW(fd,20), RFIFOW(fd,22), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28)));
 
 	//Player has been saved already, remove him from memory. [Skotlex]	
 	map_quit(sd);
@@ -390,8 +352,7 @@ int chrif_changemapserverack(int fd)
 
 /*==========================================
  *
- *------------------------------------------
- */
+ *------------------------------------------*/
 int chrif_connectack(int fd)
 {
 	RFIFOHEAD(fd);
@@ -568,7 +529,7 @@ int auth_db_cleanup(int tid, unsigned int tick, int id, int data) {
  *
  *------------------------------------------
  */
-int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
+int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip)
 {
 	nullpo_retr(-1, sd);
 
@@ -581,7 +542,7 @@ int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip)
 	WFIFOL(char_fd, 2) = sd->bl.id;
 	WFIFOL(char_fd, 6) = sd->login_id1;
 	WFIFOL(char_fd,10) = sd->login_id2;
-	WFIFOL(char_fd,14) = s_ip;
+	WFIFOL(char_fd,14) = htonl(s_ip);
 	WFIFOSET(char_fd,18);
 
 	return 0;
@@ -693,7 +654,6 @@ int chrif_changesex(int id, int sex) {
 	WFIFOW(char_fd,2) = 9;
 	WFIFOL(char_fd,4) = id;
 	WFIFOB(char_fd,8) = sex;
-//	ShowInfo("chrif : sent 0x3000(changesex)\n");
 	WFIFOSET(char_fd,9);
 	return 0;
 }
@@ -1040,7 +1000,8 @@ int chrif_accountban(int fd)
 
 //Disconnect the player out of the game, simple packet
 //packet.w AID.L WHY.B 2+4+1 = 7byte
-int chrif_disconnectplayer(int fd){
+int chrif_disconnectplayer(int fd)
+{
 	struct map_session_data *sd;
 	RFIFOHEAD(fd);
 
@@ -1419,7 +1380,7 @@ int chrif_disconnect(int fd) {
 
 void chrif_update_ip(int fd)
 {
-	unsigned long new_ip;
+	uint32 new_ip;
 	WFIFOHEAD(fd, 6);
 	new_ip = host2ip(char_ip_str);
 	if (new_ip && new_ip != char_ip)
@@ -1428,7 +1389,7 @@ void chrif_update_ip(int fd)
 	new_ip = clif_refresh_ip();
 	if (!new_ip) return; //No change
 	WFIFOW(fd, 0) = 0x2736;
-	WFIFOL(fd, 2) = new_ip;
+	WFIFOL(fd, 2) = htonl(new_ip);
 	WFIFOSET(fd, 6);
 }
 
@@ -1452,7 +1413,7 @@ int chrif_parse(int fd)
 		return 0;
 	}
 
-	while (RFIFOREST(fd) >= 2 && !session[fd]->eof) { //Infinite loop on broken pipe fix. [Skotlex]
+	while (RFIFOREST(fd) >= 2) { //Infinite loop on broken pipe fix. [Skotlex]
 		RFIFOHEAD(fd);
 		cmd = RFIFOW(fd,0);
 		if (cmd < 0x2af8 || cmd >= 0x2af8 + (sizeof(packet_len_table) / sizeof(packet_len_table[0])) ||

+ 6 - 6
src/map/chrif.h

@@ -12,11 +12,11 @@ struct auth_node{
 	unsigned int node_created; //For node auto-deleting
 };
 
-void chrif_setuserid(char*);
-void chrif_setpasswd(char*);
+void chrif_setuserid(char* id);
+void chrif_setpasswd(char* pwd);
 void chrif_checkdefaultlogin(void);
-int chrif_setip(const char*);
-void chrif_setport(int);
+int chrif_setip(const char* ip);
+void chrif_setport(uint16 port);
 
 int chrif_isconnect(void);
 
@@ -27,9 +27,9 @@ void chrif_authreq(struct map_session_data *);
 void chrif_authok(int fd);
 int chrif_scdata_request(int account_id, int char_id);
 int chrif_save(struct map_session_data*, int flag);
-int chrif_charselectreq(struct map_session_data *sd, unsigned long s_ip);
+int chrif_charselectreq(struct map_session_data*sd, uint32 s_ip);
 void check_fake_id(int fd, struct map_session_data *sd, int target_id);
-int chrif_changemapserver(struct map_session_data *sd,short map,int x,int y,int ip,short port);
+int chrif_changemapserver(struct map_session_data*sd, short map, int x, int y, uint32 ip, uint16 port);
 
 int chrif_searchcharid(int char_id);
 int chrif_changegm(int id,const char *pass,int len);

+ 23 - 28
src/map/clif.c

@@ -96,9 +96,9 @@ struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
 //Guarantees that the given string does not exceeds the allowed size, as well as making sure it's null terminated. [Skotlex\]
 #define mes_len_check(mes, len, max) if (len > max) { mes[max-1] = '\0'; len = max; } else mes[len-1] = '\0';
 static char map_ip_str[128];
-static in_addr_t map_ip;
-static in_addr_t bind_ip = INADDR_ANY;
-static int map_port = 5121;
+static uint32 map_ip;
+static uint32 bind_ip = INADDR_ANY;
+static uint16 map_port = 5121;
 int map_fd;
 
 //These two will be used to verify the incoming player's validity.
@@ -142,7 +142,7 @@ void clif_setbindip(const char* ip)
  * map鯖のport設定
  *------------------------------------------
  */
-void clif_setport(int port)
+void clif_setport(uint16 port)
 {
 	map_port = port;
 }
@@ -151,27 +151,21 @@ void clif_setport(int port)
  * map鯖のip読み出し
  *------------------------------------------
  */
-in_addr_t clif_getip(void)
+uint32 clif_getip(void)
 {
 	return map_ip;
 }
 
-//Returns the ip casted as a basic type, to avoid needing to include the socket/net related libs by calling modules.
-unsigned long clif_getip_long(void)
-{
-	return (unsigned long)map_ip;
-}
-
 //Refreshes map_server ip, returns the new ip if the ip changed, otherwise it returns 0.
-unsigned long clif_refresh_ip(void)
+uint32 clif_refresh_ip(void)
 {
-	in_addr_t new_ip;
+	uint32 new_ip;
 
 	new_ip = host2ip(map_ip_str);
 	if (new_ip && new_ip != map_ip) {
 		map_ip = new_ip;
-		ShowInfo("Updating IP resolution of [%s].\n",map_ip_str);
-		return (unsigned long)map_ip;
+		ShowInfo("Updating IP resolution of [%s].\n", map_ip_str);
+		return map_ip;
 	}
 	return 0;
 }
@@ -180,7 +174,7 @@ unsigned long clif_refresh_ip(void)
  * map鯖のport読み出し
  *------------------------------------------
  */
-int clif_getport(void)
+uint16 clif_getport(void)
 {
 	return map_port;
 }
@@ -1625,10 +1619,10 @@ int clif_changemap(struct map_session_data *sd, short map, int x, int y) {
 }
 
 /*==========================================
- *
- *------------------------------------------
- */
-int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, int ip, int port) {
+ * Tells the client to connect to another map-server
+ *------------------------------------------*/
+int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, uint32 ip, uint16 port)
+{
 	int fd;
 
 	nullpo_retr(0, sd);
@@ -1641,8 +1635,8 @@ int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x
 	WFIFOB(fd,17) = 0;	//Null terminator for mapname
 	WFIFOW(fd,18) = x;
 	WFIFOW(fd,20) = y;
-	WFIFOL(fd,22) = ip;
-	WFIFOW(fd,26) = port;
+	WFIFOL(fd,22) = htonl(ip);
+	WFIFOW(fd,26) = port; // /!\ must be sent in intel host byte order /!\ (client bug)
 	WFIFOSET(fd, packet_len(0x92));
 
 	return 0;
@@ -8862,7 +8856,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
 		/*	Rovert's Prevent logout option - Fixed [Valaris]	*/
 		if (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
 		{	//Send to char-server for character selection.
-			chrif_charselectreq(sd, session[fd]->client_addr.sin_addr.s_addr);
+			chrif_charselectreq(sd, session[fd]->client_addr);
 		} else {
 			WFIFOHEAD(fd,packet_len(0x18b));
 			WFIFOW(fd,0)=0x18b;
@@ -11746,7 +11740,8 @@ void clif_parse_debug(int fd,struct map_session_data *sd)
  * socket.cのdo_parsepacketから呼び出される
  *------------------------------------------
  */
-int clif_parse(int fd) {
+int clif_parse(int fd)
+{
 	int packet_len = 0, cmd, packet_ver, err, dump = 0;
 	TBL_PC *sd;
 	RFIFOHEAD(fd);
@@ -11772,8 +11767,8 @@ int clif_parse(int fd) {
 				map_quit(sd);
 			}
 		} else {
-			unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr;
-			ShowInfo("Closed connection from '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", ip[0],ip[1],ip[2],ip[3]);
+			uint32 ip = session[fd]->client_addr;
+			ShowInfo("Closed connection from '"CL_WHITE"%d.%d.%d.%d"CL_RESET"'.\n", CONVIP(ip));
 		}
 		do_close(fd);
 		return 0;
@@ -12321,8 +12316,8 @@ static int packetdb_readdb(void)
  *
  *------------------------------------------
  */
-int do_init_clif(void) {
-	
+int do_init_clif(void)
+{
 	clif_config.packet_db_ver = -1; // the main packet version of the DB
 	memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]
 

+ 5 - 5
src/map/clif.h

@@ -52,11 +52,11 @@ extern struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];
 
 int clif_setip(const char* ip);
 void clif_setbindip(const char* ip);
-void clif_setport(int);
+void clif_setport(uint16 port);
 
-unsigned long clif_getip_long(void);
-unsigned long clif_refresh_ip(void);
-int clif_getport(void);
+uint32 clif_getip(void);
+uint32 clif_refresh_ip(void);
+uint16 clif_getport(void);
 int clif_countusers(void);
 void clif_setwaitclose(int);
 
@@ -75,7 +75,7 @@ int clif_spawn(struct block_list*);	//area
 int clif_walkok(struct map_session_data*);	// self
 void clif_move(struct unit_data *ud); //area
 int clif_changemap(struct map_session_data*,short,int,int);	//self
-int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, int ip, int port);	//self
+int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x, int y, uint32 ip, uint16 port);	//self
 int clif_blown(struct block_list *); // area
 int clif_slide(struct block_list *,int,int); // area
 int clif_fixpos(struct block_list *);	// area

+ 10 - 11
src/map/map.c

@@ -2077,9 +2077,9 @@ int map_mapindex2mapid(unsigned short mapindex) {
 
 /*==========================================
  * 他鯖map名からip,port?換
- *------------------------------------------
- */
-int map_mapname2ipport(unsigned short name,int *ip,int *port) {
+ *------------------------------------------*/
+int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port)
+{
 	struct map_data_other_server *mdos=NULL;
 
 	mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)name);
@@ -2349,16 +2349,17 @@ static void* create_map_data_other_server(DBKey key, va_list args) {
 }
 /*==========================================
  * 他鯖管理のマップをdbに追加
- *------------------------------------------
- */
-int map_setipport(unsigned short mapindex,unsigned long ip,int port) {
+ *------------------------------------------*/
+
+int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
+{
 	struct map_data_other_server *mdos=NULL;
 
 	mdos=(struct map_data_other_server *)uidb_ensure(map_db,(unsigned int)mapindex, create_map_data_other_server);
 	
 	if(mdos->gat) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
 		return 0;
-	if(ip == clif_getip_long() && port == clif_getport()) {
+	if(ip == clif_getip() && port == clif_getport()) {
 		//That's odd, we received info that we are the ones with this map, but... we don't have it.
 		ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex));
 		exit(1);
@@ -2388,12 +2389,10 @@ int map_eraseallipport(void) {
 
 /*==========================================
  * 他鯖管理のマップをdbから削除
- *------------------------------------------
- */
-int map_eraseipport(unsigned short mapindex,unsigned long ip,int port)
+ *------------------------------------------*/
+int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
 {
 	struct map_data_other_server *mdos;
-//	unsigned char *p=(unsigned char *)&ip;
 
 	mdos = uidb_get(map_db,(unsigned int)mapindex);
 	if(!mdos || mdos->gat) //Map either does not exists or is a local map.

+ 5 - 5
src/map/map.h

@@ -1109,8 +1109,8 @@ struct map_data_other_server {
 	char name[MAP_NAME_LENGTH];
 	unsigned short index; //Index is the map index used by the mapindex* functions.
 	unsigned char *gat;	// NULLŒÅ’è‚É‚µ‚Ä”»’f
-	unsigned long ip;
-	unsigned int port;
+	uint32 ip;
+	uint16 port;
 };
 
 struct flooritem_data {
@@ -1339,9 +1339,9 @@ struct map_session_data * map_id2sd(int);
 struct block_list * map_id2bl(int);
 int map_mapindex2mapid(unsigned short mapindex);
 int map_mapname2mapid(const char* name);
-int map_mapname2ipport(unsigned short,int*,int*);
-int map_setipport(unsigned short map,unsigned long ip,int port);
-int map_eraseipport(unsigned short map,unsigned long ip,int port);
+int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port);
+int map_setipport(unsigned short map, uint32 ip, uint16 port);
+int map_eraseipport(unsigned short map, uint32 ip, uint16 port);
 int map_eraseallipport(void);
 void map_addiddb(struct block_list *);
 void map_deliddb(struct block_list *bl);

+ 8 - 7
src/map/pc.c

@@ -698,20 +698,20 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
 	sd->state.event_kill_mob = 1;
 
 	{	//Add IP field
-		unsigned char *ip = (unsigned char *) &session[sd->fd]->client_addr.sin_addr;
+		uint32 ip = session[sd->fd]->client_addr;
 		if (pc_isGM(sd))
 			ShowInfo("GM '"CL_WHITE"%s"CL_RESET"' logged in."
 				" (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
 				" Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"',"
 				" GM Level '"CL_WHITE"%d"CL_RESET"').\n",
 				sd->status.name, sd->status.account_id, sd->status.char_id,
-				sd->packet_ver, ip[0],ip[1],ip[2],ip[3], pc_isGM(sd));
+				sd->packet_ver, CONVIP(ip), pc_isGM(sd));
 		else
 			ShowInfo("'"CL_WHITE"%s"CL_RESET"' logged in."
 				" (AID/CID: '"CL_WHITE"%d/%d"CL_RESET"',"
 				" Packet Ver: '"CL_WHITE"%d"CL_RESET"', IP: '"CL_WHITE"%d.%d.%d.%d"CL_RESET"').\n",
 				sd->status.name, sd->status.account_id, sd->status.char_id,
-				sd->packet_ver, ip[0],ip[1],ip[2],ip[3]);
+				sd->packet_ver, CONVIP(ip));
 	}
 	
 	// Send friends list
@@ -3371,10 +3371,11 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
 			sd->regen.state.gc = 0;
 	}
 
-	if(m<0){
-		if(sd->mapindex){
-			int ip,port;
-			if(map_mapname2ipport(mapindex,&ip,&port)==0){
+	if(m<0) {
+		if(sd->mapindex) {
+			uint32 ip;
+			uint16 port;
+			if(map_mapname2ipport(mapindex,&ip,&port)==0) {
 				unit_remove_map(&sd->bl,clrtype);
 				sd->mapindex = mapindex;
 				sd->bl.x=x;

Неке датотеке нису приказане због велике количине промена