#include #include #include #include "ppp.h" #include "ppp_ipcp.h" #include "log.h" #include "ipdb.h" #include "events.h" #include "memdebug.h" static in_addr_t conf_wins1; static in_addr_t conf_wins2; static struct ipcp_option_t *wins1_init(struct ppp_ipcp_t *ipcp); static struct ipcp_option_t *wins2_init(struct ppp_ipcp_t *ipcp); static void wins_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt); static int wins_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr); static int wins_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr); static int wins_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr); static void wins1_print(void (*print)(const char *fmt, ...), struct ipcp_option_t *, uint8_t *ptr); static void wins2_print(void (*print)(const char *fmt, ...), struct ipcp_option_t *, uint8_t *ptr); struct wins_option_t { struct ipcp_option_t opt; in_addr_t addr; }; static struct ipcp_option_handler_t wins1_opt_hnd = { .init = wins1_init, .send_conf_req = wins_send_conf_req, .send_conf_nak = wins_send_conf_nak, .recv_conf_req = wins_recv_conf_req, .free = wins_free, .print = wins1_print, }; static struct ipcp_option_handler_t wins2_opt_hnd = { .init = wins2_init, .send_conf_req = wins_send_conf_req, .send_conf_nak = wins_send_conf_nak, .recv_conf_req = wins_recv_conf_req, .free = wins_free, .print = wins2_print, }; static struct ipcp_option_t *wins1_init(struct ppp_ipcp_t *ipcp) { struct wins_option_t *wins_opt = _malloc(sizeof(*wins_opt)); memset(wins_opt, 0, sizeof(*wins_opt)); wins_opt->opt.id = CI_WINS1; wins_opt->opt.len = 6; wins_opt->addr = conf_wins1; return &wins_opt->opt; } static struct ipcp_option_t *wins2_init(struct ppp_ipcp_t *ipcp) { struct wins_option_t *wins_opt = _malloc(sizeof(*wins_opt)); memset(wins_opt, 0, sizeof(*wins_opt)); wins_opt->opt.id = CI_WINS2; wins_opt->opt.len = 6; wins_opt->addr = conf_wins2; return &wins_opt->opt; } static void wins_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt) { struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt); _free(wins_opt); } static int wins_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr) { return 0; } static int wins_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr) { struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt); struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr; opt32->hdr.id = wins_opt->opt.id; opt32->hdr.len = 6; opt32->val = wins_opt->addr; return 6; } static int wins_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr) { struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt); struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr; if (opt32->hdr.len != 6) return IPCP_OPT_REJ; if (!wins_opt->addr) { wins_opt->addr = opt32->val; return IPCP_OPT_ACK; } if (wins_opt->addr == opt32->val) return IPCP_OPT_ACK; return IPCP_OPT_NAK; } static void wins1_print(void (*print)(const char *fmt, ...), struct ipcp_option_t *opt, uint8_t *ptr) { struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt); struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr; struct in_addr in; if (ptr) in.s_addr = opt32->val; else in.s_addr = wins_opt->addr; print("", inet_ntoa(in)); } static void wins2_print(void (*print)(const char *fmt, ...), struct ipcp_option_t *opt, uint8_t *ptr) { struct wins_option_t *wins_opt = container_of(opt, typeof(*wins_opt), opt); struct ipcp_opt32_t *opt32 = (struct ipcp_opt32_t *)ptr; struct in_addr in; if (ptr) in.s_addr = opt32->val; else in.s_addr = wins_opt->addr; print("", inet_ntoa(in)); } static void ev_wins(struct ev_wins_t *ev) { struct wins_option_t *wins_opt; struct ppp_t *ppp; if (!ev->ses->ctrl->ppp) return; ppp = container_of(ev->ses, typeof(*ppp), ses); wins_opt = container_of(ipcp_find_option(ppp, &wins1_opt_hnd), typeof(*wins_opt), opt); wins_opt->addr = ev->wins1; wins_opt = container_of(ipcp_find_option(ppp, &wins2_opt_hnd), typeof(*wins_opt), opt); wins_opt->addr = ev->wins2; } static void load_config(void) { char *opt; opt = conf_get_opt("wins", "wins1"); if (opt) conf_wins1 = inet_addr(opt); opt = conf_get_opt("wins", "wins2"); if (opt) conf_wins2 = inet_addr(opt); } static void wins_opt_init() { ipcp_option_register(&wins1_opt_hnd); ipcp_option_register(&wins2_opt_hnd); load_config(); triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config); triton_event_register_handler(EV_WINS, (triton_event_func)ev_wins); } DEFINE_INIT(4, wins_opt_init);