cbcp.c
来自「eCos操作系统源码」· C语言 代码 · 共 479 行
C
479 行
//==========================================================================//// src/cbcp.c////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Portions created by Nick Garnett are// Copyright (C) 2003 eCosCentric Ltd.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD, // FreeBSD or other sources, and are covered by the appropriate// copyright disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================/* * cbcp - Call Back Configuration Protocol. * * Copyright (c) 1995 Pedro Roque Marques * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Pedro Roque Marques. The name of the author may not be used to * endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lint//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/cbcp.c,v 1.4 1999/08/28 01:19:00 peter Exp $";#endif#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/time.h>#include <cyg/ppp/syslog.h>#include "cyg/ppp/pppd.h"#include "cyg/ppp/cbcp.h"#include "cyg/ppp/fsm.h"#include "cyg/ppp/lcp.h"#include "cyg/ppp/ipcp.h"/* * Protocol entry points. */static void cbcp_init __P((int unit));static void cbcp_open __P((int unit));static void cbcp_lowerup __P((int unit));static void cbcp_input __P((int unit, u_char *pkt, int len));static void cbcp_protrej __P((int unit));static int cbcp_printpkt __P((u_char *pkt, int len, void (*printer) __P((void *, char *, ...)), void *arg));struct protent cbcp_protent = { PPP_CBCP, cbcp_init, cbcp_input, cbcp_protrej, cbcp_lowerup, NULL, cbcp_open, NULL, cbcp_printpkt, NULL, 0, "CBCP", NULL, NULL, NULL};cbcp_state cbcp[NUM_PPP]; /* internal prototypes */static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));static void cbcp_resp __P((cbcp_state *us));static void cbcp_up __P((cbcp_state *us));static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));/* init state */static voidcbcp_init(iface) int iface;{ cbcp_state *us; us = &cbcp[iface]; memset(us, 0, sizeof(cbcp_state)); us->us_unit = iface; us->us_type |= (1 << CB_CONF_NO);}/* lower layer is up */static voidcbcp_lowerup(iface) int iface;{ cbcp_state *us = &cbcp[iface]; syslog(LOG_DEBUG, "cbcp_lowerup"); syslog(LOG_DEBUG, "want: %d", us->us_type); if (us->us_type == CB_CONF_USER) syslog(LOG_DEBUG, "phone no: %s", us->us_number);}static voidcbcp_open(unit) int unit;{ syslog(LOG_DEBUG, "cbcp_open");}/* process an incomming packet */static voidcbcp_input(unit, inpacket, pktlen) int unit; u_char *inpacket; int pktlen;{ u_char *inp; u_char code, id; u_short len; cbcp_state *us = &cbcp[unit]; inp = inpacket; if (pktlen < CBCP_MINLEN) { syslog(LOG_ERR, "CBCP packet is too small"); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp);#if 0 if (len > pktlen) { syslog(LOG_ERR, "CBCP packet: invalid length"); return; }#endif len -= CBCP_MINLEN; switch(code) { case CBCP_REQ: us->us_id = id; cbcp_recvreq(us, inp, len); break; case CBCP_RESP: syslog(LOG_DEBUG, "CBCP_RESP received"); break; case CBCP_ACK: if (id != us->us_id) syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d", us->us_id, id); cbcp_recvack(us, inp, len); break; default: break; }}/* protocol was rejected by foe */void cbcp_protrej(int iface){}char *cbcp_codenames[] = { "Request", "Response", "Ack"};char *cbcp_optionnames[] = { "NoCallback", "UserDefined", "AdminDefined", "List"};/* pretty print a packet */static intcbcp_printpkt(p, plen, printer, arg) u_char *p; int plen; void (*printer) __P((void *, char *, ...)); void *arg;{ int code, opt, id, len, olen, delay; u_char *pstart; if (plen < HEADERLEN) return 0; pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *)) printer(arg, " %s", cbcp_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= HEADERLEN; switch (code) { case CBCP_REQ: case CBCP_RESP: case CBCP_ACK: while(len >= 2) { GETCHAR(opt, p); GETCHAR(olen, p); if (olen < 2 || olen > len) { break; } printer(arg, " <"); len -= olen; if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *)) printer(arg, " %s", cbcp_optionnames[opt-1]); else printer(arg, " option=0x%x", opt); if (olen > 2) { GETCHAR(delay, p); printer(arg, " delay = %d", delay); } if (olen > 3) { int addrt; char str[256]; GETCHAR(addrt, p); memcpy(str, p, olen - 4); str[olen - 4] = 0; printer(arg, " number = %s", str); } printer(arg, ">"); break; } default: break; } for (; len > 0; --len) { GETCHAR(code, p); printer(arg, " %.2x", code); } return p - pstart;}/* received CBCP request */static voidcbcp_recvreq(us, pckt, pcktlen) cbcp_state *us; char *pckt; int pcktlen;{ u_char type, opt_len, delay, addr_type; char address[256]; int len = pcktlen; address[0] = 0; while (len) { syslog(LOG_DEBUG, "length: %d", len); GETCHAR(type, pckt); GETCHAR(opt_len, pckt); if (opt_len > 2) GETCHAR(delay, pckt); us->us_allowed |= (1 << type); switch(type) { case CB_CONF_NO: syslog(LOG_DEBUG, "no callback allowed"); break; case CB_CONF_USER: syslog(LOG_DEBUG, "user callback allowed"); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) syslog(LOG_DEBUG, "address: %s", address); } break; case CB_CONF_ADMIN: syslog(LOG_DEBUG, "user admin defined allowed"); break; case CB_CONF_LIST: break; } len -= opt_len; } cbcp_resp(us);}static voidcbcp_resp(us) cbcp_state *us;{ u_char cb_type; u_char buf[256]; u_char *bufp = buf; int len = 0; cb_type = us->us_allowed & us->us_type; syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type);#if 0 if (!cb_type) lcp_down(us->us_unit);#endif if (cb_type & ( 1 << CB_CONF_USER ) ) { syslog(LOG_DEBUG, "cbcp_resp CONF_USER"); PUTCHAR(CB_CONF_USER, bufp); len = 3 + 1 + strlen(us->us_number) + 1; PUTCHAR(len , bufp); PUTCHAR(5, bufp); /* delay */ PUTCHAR(1, bufp); BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); cbcp_send(us, CBCP_RESP, buf, len); return; } if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN"); PUTCHAR(CB_CONF_ADMIN, bufp); len = 3 + 1; PUTCHAR(len , bufp); PUTCHAR(5, bufp); /* delay */ PUTCHAR(0, bufp); cbcp_send(us, CBCP_RESP, buf, len); return; } if (cb_type & ( 1 << CB_CONF_NO ) ) { syslog(LOG_DEBUG, "cbcp_resp CONF_NO"); PUTCHAR(CB_CONF_NO, bufp); len = 3; PUTCHAR(len , bufp); PUTCHAR(0, bufp); cbcp_send(us, CBCP_RESP, buf, len); (*ipcp_protent.open)(us->us_unit); return; }}static voidcbcp_send(us, code, buf, len) cbcp_state *us; u_char code; u_char *buf; int len;{ u_char *outp; int outlen; outp = outpacket_buf; outlen = 4 + len; MAKEHEADER(outp, PPP_CBCP); PUTCHAR(code, outp); PUTCHAR(us->us_id, outp); PUTSHORT(outlen, outp); if (len) BCOPY(buf, outp, len); output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);}static voidcbcp_recvack(us, pckt, len) cbcp_state *us; char *pckt; int len;{ u_char type, delay, addr_type; int opt_len; char address[256]; if (len) { GETCHAR(type, pckt); GETCHAR(opt_len, pckt); if (opt_len > 2) GETCHAR(delay, pckt); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) syslog(LOG_DEBUG, "peer will call: %s", address); } } cbcp_up(us);}extern int persist;/* ok peer will do callback */static voidcbcp_up(us) cbcp_state *us;{ persist = 0; lcp_close(0, "Call me back, please");}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?