diff options
Diffstat (limited to 'src/login')
-rw-r--r-- | src/login/lclif.c | 30 | ||||
-rw-r--r-- | src/login/lclif.h | 78 | ||||
-rw-r--r-- | src/login/lclif.p.h | 129 | ||||
-rw-r--r-- | src/login/login.c | 4 | ||||
-rw-r--r-- | src/login/login.h | 4 |
5 files changed, 199 insertions, 46 deletions
diff --git a/src/login/lclif.c b/src/login/lclif.c index c869282c9..07193ac0f 100644 --- a/src/login/lclif.c +++ b/src/login/lclif.c @@ -37,12 +37,17 @@ #include "common/strlib.h" #include "common/utils.h" +/** @file + * Implementation of the login client interface. + */ + struct lclif_interface lclif_s; struct lclif_interface_private lclif_p; struct lclif_interface *lclif; -struct login_packet_db packet_db[MAX_PACKET_DB + 1]; +struct login_packet_db packet_db[MAX_PACKET_DB + 1]; ///< Packet database. +/// @copydoc lclif_interface::connection_error() void lclif_connection_error(int fd, uint8 error) { struct packet_SC_NOTIFY_BAN *packet = NULL; @@ -53,12 +58,14 @@ void lclif_connection_error(int fd, uint8 error) WFIFOSET(fd, sizeof(*packet)); } +/// @copydoc lclif_interface_private::parse_CA_CONNECT_INFO_CHANGED() enum parsefunc_rcode lclif_parse_CA_CONNECT_INFO_CHANGED(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_CONNECT_INFO_CHANGED(int fd, struct login_session_data *sd) { return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_EXE_HASHCHECK() enum parsefunc_rcode lclif_parse_CA_EXE_HASHCHECK(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_EXE_HASHCHECK(int fd, struct login_session_data *sd) { @@ -68,6 +75,7 @@ enum parsefunc_rcode lclif_parse_CA_EXE_HASHCHECK(int fd, struct login_session_d return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_LOGIN() enum parsefunc_rcode lclif_parse_CA_LOGIN(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_LOGIN(int fd, struct login_session_data *sd) { @@ -86,6 +94,7 @@ enum parsefunc_rcode lclif_parse_CA_LOGIN(int fd, struct login_session_data *sd) return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_LOGIN2() enum parsefunc_rcode lclif_parse_CA_LOGIN2(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_LOGIN2(int fd, struct login_session_data *sd) { @@ -101,6 +110,7 @@ enum parsefunc_rcode lclif_parse_CA_LOGIN2(int fd, struct login_session_data *sd return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_LOGIN3() enum parsefunc_rcode lclif_parse_CA_LOGIN3(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_LOGIN3(int fd, struct login_session_data *sd) { @@ -118,6 +128,7 @@ enum parsefunc_rcode lclif_parse_CA_LOGIN3(int fd, struct login_session_data *sd return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_LOGIN4() enum parsefunc_rcode lclif_parse_CA_LOGIN4(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_LOGIN4(int fd, struct login_session_data *sd) { @@ -135,6 +146,7 @@ enum parsefunc_rcode lclif_parse_CA_LOGIN4(int fd, struct login_session_data *sd return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_LOGIN_PCBANG() enum parsefunc_rcode lclif_parse_CA_LOGIN_PCBANG(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_LOGIN_PCBANG(int fd, struct login_session_data *sd) { @@ -156,6 +168,7 @@ enum parsefunc_rcode lclif_parse_CA_LOGIN_PCBANG(int fd, struct login_session_da return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_LOGIN_HAN() enum parsefunc_rcode lclif_parse_CA_LOGIN_HAN(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_LOGIN_HAN(int fd, struct login_session_data *sd) { @@ -178,6 +191,7 @@ enum parsefunc_rcode lclif_parse_CA_LOGIN_HAN(int fd, struct login_session_data return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_SSO_LOGIN_REQ() enum parsefunc_rcode lclif_parse_CA_SSO_LOGIN_REQ(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_SSO_LOGIN_REQ(int fd, struct login_session_data *sd) { @@ -203,6 +217,7 @@ enum parsefunc_rcode lclif_parse_CA_SSO_LOGIN_REQ(int fd, struct login_session_d return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_REQ_HASH() enum parsefunc_rcode lclif_parse_CA_REQ_HASH(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_REQ_HASH(int fd, struct login_session_data *sd) { @@ -214,6 +229,7 @@ enum parsefunc_rcode lclif_parse_CA_REQ_HASH(int fd, struct login_session_data * return PACKET_VALID; } +/// @copydoc lclif_interface_private::parse_CA_CHARSERVERCONNECT() enum parsefunc_rcode lclif_parse_CA_CHARSERVERCONNECT(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); enum parsefunc_rcode lclif_parse_CA_CHARSERVERCONNECT(int fd, struct login_session_data *sd) { @@ -226,6 +242,7 @@ enum parsefunc_rcode lclif_parse_CA_CHARSERVERCONNECT(int fd, struct login_sessi return PACKET_STOPPARSE; } +/// @copydoc lclif_interface::server_list() bool lclif_send_server_list(struct login_session_data *sd) { int server_num = 0, i, n, length; @@ -279,6 +296,7 @@ bool lclif_send_server_list(struct login_session_data *sd) return true; } +/// @copydoc lclif_interface::auth_failed() void lclif_send_auth_failed(int fd, time_t ban, uint32 error) { #if PACKETVER >= 20120000 /* not sure when this started */ @@ -299,6 +317,7 @@ void lclif_send_auth_failed(int fd, time_t ban, uint32 error) WFIFOSET(fd, sizeof(*packet)); } +/// @copydoc lclif_interface::login_error() void lclif_send_login_error(int fd, uint8 error) { struct packet_AC_REFUSE_LOGIN *packet = NULL; @@ -310,6 +329,7 @@ void lclif_send_login_error(int fd, uint8 error) WFIFOSET(fd, sizeof(*packet)); } +/// @copydoc lclif_interface::coding_key() void lclif_send_coding_key(int fd, struct login_session_data *sd) __attribute__((nonnull (2))); void lclif_send_coding_key(int fd, struct login_session_data *sd) { @@ -324,6 +344,7 @@ void lclif_send_coding_key(int fd, struct login_session_data *sd) WFIFOSET(fd, size); } +/// @copydoc lclif_interface::parse() int lclif_parse(int fd) { struct login_session_data *sd = NULL; @@ -389,6 +410,7 @@ int lclif_parse(int fd) return 0; } +/// @copydoc lclif_interface_private::parse_sub() enum parsefunc_rcode lclif_parse_sub(int fd, struct login_session_data *sd) { int packet_len = (int)RFIFOREST(fd); @@ -436,6 +458,7 @@ enum parsefunc_rcode lclif_parse_sub(int fd, struct login_session_data *sd) return PACKET_VALID; } +/// @copydoc lclif_interface::packet() const struct login_packet_db *lclif_packet(int16 packet_id) { if (packet_id == PACKET_ID_CA_CHARSERVERCONNECT) @@ -447,6 +470,7 @@ const struct login_packet_db *lclif_packet(int16 packet_id) return &packet_db[packet_id]; } +/// @copydoc lclif_interface::parse_packet() enum parsefunc_rcode lclif_parse_packet(const struct login_packet_db *lpd, int fd, struct login_session_data *sd) { int result; @@ -455,6 +479,7 @@ enum parsefunc_rcode lclif_parse_packet(const struct login_packet_db *lpd, int f return result; } +/// @copydoc lclif_interface_private::packetdb_loaddb() void packetdb_loaddb(void) { int i; @@ -494,15 +519,18 @@ void packetdb_loaddb(void) packet_db[0].pFunc = &lclif->p->parse_CA_CHARSERVERCONNECT; } +/// @copydoc lclif_interface::init() void lclif_init(void) { lclif->p->packetdb_loaddb(); } +/// @copydoc lclif_interface::final() void lclif_final(void) { } +/// Interface base initialization. void lclif_defaults(void) { lclif = &lclif_s; diff --git a/src/login/lclif.h b/src/login/lclif.h index 5eb5a75aa..d1e4317a2 100644 --- a/src/login/lclif.h +++ b/src/login/lclif.h @@ -22,6 +22,10 @@ #include "common/hercules.h" +/** @file + * Login Client Interface. + **/ + /* Forward Declarations */ struct login_session_data; struct lclif_interface_private; @@ -41,25 +45,99 @@ enum parsefunc_rcode { typedef enum parsefunc_rcode (LoginParseFunc)(int fd, struct login_session_data *sd); /* Structs */ + /// Login packet DB entry struct login_packet_db { int16 len; ///< Packet length LoginParseFunc **pFunc; ///< Packet parsing function }; +/// The login clif (client interface) interface. struct lclif_interface { struct lclif_interface_private *p; ///< Private interface + /// Interface initialization. void (*init)(void); + + /// Interface finalization. void (*final)(void); + /** + * Reports a connection error to the client. + * + * @param fd Client connection file descriptor. + * @param error Error code. + * @see #PACKET_SC_NOTIFY_BAN. + */ void (*connection_error)(int fd, uint8 error); + + /** + * Sends the character server list to the client. + * + * @param sd The client to send to. + * @return Success status. + * @retval false in case of failure (no server available). + * @see #PACKET_AC_ACCEPT_LOGIN. + */ bool (*server_list)(struct login_session_data *sd); + + /** + * Reports an authentication failure to the client. + * + * @param fd The client connection file descriptor. + * @param ban The ban duration (if error == 6). + * @param error The authentication error code. + * @see #PACKET_ID_AC_REFUSE_LOGIN. + * @see #PACKET_ID_AC_REFUSE_LOGIN_R2. + */ void (*auth_failed)(int fd, time_t ban, uint32 error); + + /** + * Reports a login error to the client. + * + * @param fd Client connection file descriptor. + * @param error Error code. + * @see #PACKET_AC_REFUSE_LOGIN. + */ void (*login_error)(int fd, uint8 error); + + /** + * Sends an authentication challenge to the client. + * + * @param fd Client connection file descriptor. + * @param sd The client to send to. + * @see #PACKET_AC_ACK_HASH. + */ void (*coding_key)(int fd, struct login_session_data *sd); + + /** + * Retrieves a packet's data from the packet db. + * + * @param packet_id The packet id. + * @return The packet data. + * @retval NULL if the packet doesn't exist. + */ const struct login_packet_db *(*packet)(int16 packet_id); + + /** + * Parses a packet. + * + * @param lpd Packet database entry. + * @param fd Client connection file descriptor. + * @param sd Session data. + * @return Parse result error code. + */ enum parsefunc_rcode (*parse_packet)(const struct login_packet_db *lpd, int fd, struct login_session_data *sd); + + /** + * Packet parser loop function. + * + * Parses packets received from a client. + * + * @param fd Client connection file descriptor. + * @return error code. + * @retval 0 in case of success. + */ int (*parse)(int fd); }; diff --git a/src/login/lclif.p.h b/src/login/lclif.p.h index b0811c7c6..e57c5e50d 100644 --- a/src/login/lclif.p.h +++ b/src/login/lclif.p.h @@ -20,6 +20,10 @@ #ifndef LOGIN_LCLIF_P_H #define LOGIN_LCLIF_P_H +/** @file + * Private header for the login client interface. + */ + #include "login/lclif.h" #include "common/hercules.h" @@ -194,59 +198,83 @@ struct packet_CA_REQ_HASH { int16 packet_id; ///< Packet ID (#PACKET_ID_CA_REQ_HASH) } __attribute__((packed)); +/** + * Packet structure for CA_CHARSERVERCONNECT. + * + * This packet is used internally, to signal a char-server connection. + */ struct packet_CA_CHARSERVERCONNECT { - int16 packet_id; - char userid[24]; - char password[24]; + int16 packet_id; ///< Packet ID (#PACKET_ID_CA_CHARSERVERCONNECT) + char userid[24]; ///< Username + char password[24]; ///< Password int32 unknown; - int32 ip; - int16 port; - char name[20]; + int32 ip; ///< Charserver IP + int16 port; ///< Charserver port + char name[20]; ///< Charserver name int16 unknown2; - int16 type; - int16 new; + int16 type; ///< Charserver type + int16 new; ///< Whether charserver is to be marked as new } __attribute__((packed)); +/** + * Packet structure for SC_NOTIFY_BAN. + */ struct packet_SC_NOTIFY_BAN { - int16 packet_id; - uint8 error_code; + int16 packet_id; ///< Packet ID (#PACKET_ID_SC_NOTIFY_BAN) + uint8 error_code; ///< Error code } __attribute__((packed)); +/** + * Packet structure for AC_REFUSE_LOGIN. + */ struct packet_AC_REFUSE_LOGIN { - int16 packet_id; - uint8 error_code; - char block_date[20]; + int16 packet_id; ///< Packet ID (#PACKET_ID_AC_REFUSE_LOGIN) + uint8 error_code; ///< Error code + char block_date[20]; ///< Ban expiration date } __attribute__((packed)); +/** + * Packet structure for AC_REFUSE_LOGIN_R2. + */ struct packet_AC_REFUSE_LOGIN_R2 { - int16 packet_id; - uint32 error_code; - char block_date[20]; + int16 packet_id; ///< Packet ID (#PACKET_ID_AC_REFUSE_LOGIN_R2) + uint32 error_code; ///< Error code + char block_date[20]; ///< Ban expiration date } __attribute__((packed)); +/** + * Packet structure for AC_ACCEPT_LOGIN. + * + * Variable-length packet. + */ struct packet_AC_ACCEPT_LOGIN { - int16 packet_id; - int16 packet_len; - int32 auth_code; - uint32 aid; - uint32 user_level; - uint32 last_login_ip; - char last_login_time[26]; - uint8 sex; + int16 packet_id; ///< Packet ID (#PACKET_ID_AC_ACCEPT_LOGIN) + int16 packet_len; ///< Packet length (variable length) + int32 auth_code; ///< Authentication code + uint32 aid; ///< Account ID + uint32 user_level; ///< User level + uint32 last_login_ip; ///< Last login IP + char last_login_time[26]; ///< Last login timestamp + uint8 sex; ///< Account sex struct { - uint32 ip; - int16 port; - char name[20]; - uint16 usercount; - uint16 state; - uint16 property; - } server_list[]; + uint32 ip; ///< Server IP address + int16 port; ///< Server port + char name[20]; ///< Server name + uint16 usercount; ///< Online users + uint16 state; ///< Server state + uint16 property; ///< Server property + } server_list[]; ///< List of charservers } __attribute__((packed)); +/** + * Packet structure for AC_ACK_HASH. + * + * Variable-length packet + */ struct packet_AC_ACK_HASH { - int16 packet_id; - int16 packet_len; - uint8 secret[]; + int16 packet_id; ///< Packet ID (#PACKET_ID_AC_ACK_HASH) + int16 packet_len; ///< Packet length (variable length) + uint8 secret[]; ///< Challenge string } __attribute__((packed)); #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute @@ -257,20 +285,31 @@ struct packet_AC_ACK_HASH { * Login Client Interface Private Interface */ struct lclif_interface_private { + /** + * Populates the packet database. + */ void (*packetdb_loaddb)(void); + + /** + * Attempts to validate and parse a received packet. + * + * @param fd Client connection file descriptor. + * @param sd Session data. + * @return Parse result error code. + */ enum parsefunc_rcode (*parse_sub)(int fd, struct login_session_data *sd); - LoginParseFunc *parse_CA_CONNECT_INFO_CHANGED; - LoginParseFunc *parse_CA_EXE_HASHCHECK; - LoginParseFunc *parse_CA_LOGIN; - LoginParseFunc *parse_CA_LOGIN2; - LoginParseFunc *parse_CA_LOGIN3; - LoginParseFunc *parse_CA_LOGIN4; - LoginParseFunc *parse_CA_LOGIN_PCBANG; - LoginParseFunc *parse_CA_LOGIN_HAN; - LoginParseFunc *parse_CA_SSO_LOGIN_REQ; - LoginParseFunc *parse_CA_REQ_HASH; - LoginParseFunc *parse_CA_CHARSERVERCONNECT; + LoginParseFunc *parse_CA_CONNECT_INFO_CHANGED; ///< Packet handler for #packet_CA_CONNECT_INFO_CHANGED. + LoginParseFunc *parse_CA_EXE_HASHCHECK; ///< Packet handler for #packet_CA_EXE_HASHCHECK. + LoginParseFunc *parse_CA_LOGIN; ///< Packet handler for #packet_CA_LOGIN. + LoginParseFunc *parse_CA_LOGIN2; ///< Packet handler for #packet_CA_LOGIN2. + LoginParseFunc *parse_CA_LOGIN3; ///< Packet handler for #packet_CA_LOGIN3. + LoginParseFunc *parse_CA_LOGIN4; ///< Packet handler for #packet_CA_LOGIN4. + LoginParseFunc *parse_CA_LOGIN_PCBANG; ///< Packet handler for #packet_CA_LOGIN_PCBANG. + LoginParseFunc *parse_CA_LOGIN_HAN; ///< Packet handler for #packet_CA_LOGIN_HAN. + LoginParseFunc *parse_CA_SSO_LOGIN_REQ; ///< Packet handler for #packet_CA_SSO_LOGIN_REQ. + LoginParseFunc *parse_CA_REQ_HASH; ///< Packet handler for #packet_CA_REQ_HASH. + LoginParseFunc *parse_CA_CHARSERVERCONNECT; ///< Packet handler for #packet_CA_CHARSERVERCONNECT. }; #endif // LOGIN_LCLIF_P_H diff --git a/src/login/login.c b/src/login/login.c index 38e2651c5..d7c7321d8 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -44,6 +44,10 @@ #include <stdio.h> #include <stdlib.h> +/** @file + * Implementation of the login interface. + */ + struct login_interface login_s; struct login_interface *login; struct Login_Config login_config_; diff --git a/src/login/login.h b/src/login/login.h index 7c2e5925f..36085ae91 100644 --- a/src/login/login.h +++ b/src/login/login.h @@ -26,6 +26,10 @@ #include "common/db.h" #include "common/mmo.h" // NAME_LENGTH,SEX_* +/** @file + * Login interface. + */ + struct mmo_account; struct AccountDB; |