File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ccp_deflate.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (3 years, 4 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

    1: 
    2: /*
    3:  * ccp_deflate.c
    4:  *
    5:  * Written by Alexander Motin <mav@FreeBSD.org>
    6:  */
    7: 
    8: #include "defs.h"
    9: 
   10: #ifdef CCP_DEFLATE
   11: 
   12: #include "ppp.h"
   13: #include "ccp.h"
   14: #include "util.h"
   15: #include "ngfunc.h"
   16: 
   17: #include <netgraph/ng_message.h>
   18: #include <netgraph.h>
   19: 
   20: /*
   21:  * INTERNAL FUNCTIONS
   22:  */
   23: 
   24:   static int	DeflateInit(Bund b, int direction);
   25:   static int	DeflateConfigure(Bund b);
   26:   static char   *DeflateDescribe(Bund b, int xmit, char *buf, size_t len);
   27:   static void	DeflateCleanup(Bund b, int direction);
   28: 
   29:   static u_char	*DeflateBuildConfigReq(Bund b, u_char *cp, int *ok);
   30:   static void   DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode);
   31:   static Mbuf	DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck);
   32:   static Mbuf	DeflateSendResetReq(Bund b);
   33:   static void	DeflateRecvResetAck(Bund b, int id, Mbuf bp);
   34:   static int    DeflateNegotiated(Bund b, int xmit);
   35:   static int    DeflateSubtractBloat(Bund b, int size);
   36:   static int	DeflateStat(Context ctx, int dir);
   37: 
   38: /*
   39:  * GLOBAL VARIABLES
   40:  */
   41: 
   42:   const struct comptype	gCompDeflateInfo =
   43:   {
   44:     "deflate",
   45:     CCP_TY_DEFLATE,
   46:     2,
   47:     DeflateInit,
   48:     DeflateConfigure,
   49:     NULL,
   50:     DeflateDescribe,
   51:     DeflateSubtractBloat,
   52:     DeflateCleanup,
   53:     DeflateBuildConfigReq,
   54:     DeflateDecodeConfigReq,
   55:     DeflateSendResetReq,
   56:     DeflateRecvResetReq,
   57:     DeflateRecvResetAck,
   58:     DeflateNegotiated,
   59:     DeflateStat,
   60:     NULL,
   61:     NULL,
   62:   };
   63: 
   64: /*
   65:  * DeflateInit()
   66:  */
   67: 
   68: static int
   69: DeflateInit(Bund b, int dir)
   70: {
   71:     DeflateInfo		const deflate = &b->ccp.deflate;
   72:     struct ng_deflate_config	conf;
   73:     struct ngm_mkpeer	mp;
   74:     char		path[NG_PATHSIZ];
   75:     const char		*deflatehook, *ppphook;
   76:     ng_ID_t		id;
   77: 
   78:     /* Initialize configuration structure */
   79:     memset(&conf, 0, sizeof(conf));
   80:     conf.enable = 1;
   81:     if (dir == COMP_DIR_XMIT) {
   82: 	ppphook = NG_PPP_HOOK_COMPRESS;
   83:     	deflatehook = NG_DEFLATE_HOOK_COMP;
   84:     	conf.windowBits = deflate->xmit_windowBits;
   85:     } else {
   86:         ppphook = NG_PPP_HOOK_DECOMPRESS;
   87:         deflatehook = NG_DEFLATE_HOOK_DECOMP;
   88:         conf.windowBits = deflate->recv_windowBits;
   89:     }
   90: 
   91:     /* Attach a new DEFLATE node to the PPP node */
   92:     snprintf(path, sizeof(path), "[%x]:", b->nodeID);
   93:     strcpy(mp.type, NG_DEFLATE_NODE_TYPE);
   94:     strcpy(mp.ourhook, ppphook);
   95:     strcpy(mp.peerhook, deflatehook);
   96:     if (NgSendMsg(gCcpCsock, path,
   97:     	    NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) {
   98: 	Perror("[%s] can't create %s node", b->name, mp.type);
   99: 	return(-1);
  100:     }
  101: 
  102:     strlcat(path, ppphook, sizeof(path));
  103: 
  104:     if ((id = NgGetNodeID(-1, path)) == 0) {
  105: 	Perror("[%s] Cannot get %s node id", b->name, NG_DEFLATE_NODE_TYPE);
  106: 	goto fail;
  107:     }
  108: 
  109:     if (dir == COMP_DIR_XMIT) {
  110: 	b->ccp.comp_node_id = id;
  111:     } else {
  112: 	b->ccp.decomp_node_id = id;
  113:     }
  114: 
  115:     /* Configure DEFLATE node */
  116:     snprintf(path, sizeof(path), "[%x]:", id);
  117:     if (NgSendMsg(gCcpCsock, path,
  118:     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
  119: 	Perror("[%s] can't config %s node at %s",
  120:     	    b->name, NG_DEFLATE_NODE_TYPE, path);
  121:     	goto fail;
  122:     }
  123: 
  124:     return 0;
  125: 
  126: fail:
  127:     NgFuncShutdownNode(gCcpCsock, b->name, path);
  128:     return(-1);
  129: }
  130: 
  131: /*
  132:  * DeflateConfigure()
  133:  */
  134: 
  135: static int
  136: DeflateConfigure(Bund b)
  137: {
  138:     CcpState	const ccp = &b->ccp;
  139:     DeflateInfo	const deflate = &ccp->deflate;
  140:   
  141:     deflate->xmit_windowBits=15;
  142:     deflate->recv_windowBits=0;
  143:   
  144:     return(0);
  145: }
  146: 
  147: /*
  148:  * DeflateCleanup()
  149:  */
  150: 
  151: static char *
  152: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
  153: {
  154:     CcpState	const ccp = &b->ccp;
  155:     DeflateInfo	const deflate = &ccp->deflate;
  156: 
  157:     switch (dir) {
  158: 	case COMP_DIR_XMIT:
  159: 	    snprintf(buf, len, "win %d", deflate->xmit_windowBits);
  160: 	    break;
  161: 	case COMP_DIR_RECV:
  162: 	    snprintf(buf, len, "win %d", deflate->recv_windowBits);
  163: 	    break;
  164: 	default:
  165:     	    assert(0);
  166:     	    return(NULL);
  167:     }
  168:     return (buf);
  169: }
  170: 
  171: /*
  172:  * DeflateCleanup()
  173:  */
  174: 
  175: void
  176: DeflateCleanup(Bund b, int dir)
  177: {
  178:     char		path[NG_PATHSIZ];
  179: 
  180:     /* Remove node */
  181:     if (dir == COMP_DIR_XMIT) {
  182: 	snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
  183: 	b->ccp.comp_node_id = 0;
  184:     } else {
  185: 	snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
  186: 	b->ccp.decomp_node_id = 0;
  187:     }
  188:     NgFuncShutdownNode(gCcpCsock, b->name, path);
  189: }
  190: 
  191: /*
  192:  * DeflateRecvResetReq()
  193:  */
  194: 
  195: static Mbuf
  196: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
  197: {
  198:     char		path[NG_PATHSIZ];
  199: 
  200:     (void)bp;
  201:     (void)id;
  202:     (void)noAck;
  203: 
  204:     /* Forward ResetReq to the DEFLATE compression node */
  205:     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
  206:     if (NgSendMsg(gCcpCsock, path,
  207:     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
  208: 	Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
  209:     }
  210:     return(NULL);
  211: }
  212: 
  213: /*
  214:  * DeflateSendResetReq()
  215:  */
  216: 
  217: static Mbuf
  218: DeflateSendResetReq(Bund b)
  219: {
  220:   (void)b;
  221:   return(NULL);
  222: }
  223: 
  224: /*
  225:  * DeflateRecvResetAck()
  226:  */
  227: 
  228: static void
  229: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
  230: {
  231:     char		path[NG_PATHSIZ];
  232: 
  233:     (void)bp;
  234:     (void)id;
  235: 
  236:     /* Forward ResetReq to the DEFLATE compression node */
  237:     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
  238:     if (NgSendMsg(gCcpCsock, path,
  239:     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
  240: 	Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
  241:     }
  242: }
  243: 
  244: /*
  245:  * DeflateBuildConfigReq()
  246:  */
  247: 
  248: static u_char *
  249: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
  250: {
  251:   CcpState	const ccp = &b->ccp;
  252:   DeflateInfo	const deflate = &ccp->deflate;
  253:   u_int16_t	opt;
  254:   
  255:   if (deflate->xmit_windowBits > 0) {
  256:     opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
  257:   
  258:     cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
  259:     *ok = 1;
  260:   }
  261:   return (cp);
  262: }
  263: 
  264: /*
  265:  * DeflateDecodeConfigReq()
  266:  */
  267: 
  268: static void
  269: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
  270: {
  271:     Bund 	b = (Bund)fp->arg;
  272:   CcpState	const ccp = &b->ccp;
  273:   DeflateInfo	const deflate = &ccp->deflate;
  274:   u_int16_t     o;
  275:   u_char	window, method, chk;
  276: 
  277:   /* Sanity check */
  278:   if (opt->len != 4) {
  279:     Log(LG_CCP, ("[%s]     bogus length %d", b->name, opt->len));
  280:     if (mode == MODE_REQ)
  281:       FsmRej(fp, opt);
  282:     return;
  283:   }
  284: 
  285:   /* Get bits */
  286:   memcpy(&o, opt->data, 2);
  287:   o = ntohs(o);
  288:   window = (o>>12)&0x000F;
  289:   method = (o>>8)&0x000F;
  290:   chk = o&0x0003;
  291: 
  292:   /* Display it */
  293:   Log(LG_CCP, ("[%s]     0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
  294: 
  295:   /* Deal with it */
  296:   switch (mode) {
  297:     case MODE_REQ:
  298: 	if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
  299: 	    deflate->recv_windowBits = window + 8;
  300: 	    FsmAck(fp, opt);
  301: 	} else {
  302: 	    o = htons((7<<12) + (8<<8) + (0<<2) + 0);
  303: 	    memcpy(opt->data, &o, 2);
  304: 	    FsmNak(fp, opt);
  305: 	}
  306:       break;
  307: 
  308:     case MODE_NAK:
  309: 	if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
  310: 	    deflate->xmit_windowBits = window + 8;
  311: 	else {
  312: 	    deflate->xmit_windowBits = 0;
  313: 	}
  314:       break;
  315:   }
  316: }
  317: 
  318: /*
  319:  * DeflateNegotiated()
  320:  */
  321: 
  322: static int
  323: DeflateNegotiated(Bund b, int dir)
  324: {
  325:   (void)b;
  326:   (void)dir;
  327: 
  328:   return 1;
  329: }
  330: 
  331: /*
  332:  * DeflateSubtractBloat()
  333:  */
  334: 
  335: static int
  336: DeflateSubtractBloat(Bund b, int size)
  337: {
  338:   (void)b;
  339:   (void)size;
  340: 
  341:   return(size + CCP_OVERHEAD);  /* Compression compensate header size */
  342: }
  343: 
  344: static int
  345: DeflateStat(Context ctx, int dir) 
  346: {
  347:     Bund			b = ctx->bund;
  348:     char			path[NG_PATHSIZ];
  349:     struct ng_deflate_stats	stats;
  350:     union {
  351: 	u_char			buf[sizeof(struct ng_mesg) + sizeof(stats)];
  352: 	struct ng_mesg		reply;
  353:     }				u;
  354: 
  355:     switch (dir) {
  356: 	case COMP_DIR_XMIT:
  357: 	    snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
  358: 		NG_PPP_HOOK_COMPRESS);
  359: 	    break;
  360: 	case COMP_DIR_RECV:
  361: 	    snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
  362: 		NG_PPP_HOOK_DECOMPRESS);
  363: 	    break;
  364: 	default:
  365: 	    assert(0);
  366:     }
  367:     if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0, 
  368: 	&u.reply, sizeof(u), NULL) < 0) {
  369: 	    Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
  370: 	    return(0);
  371:     }
  372:     memcpy(&stats, u.reply.data, sizeof(stats));
  373:     switch (dir) {
  374: 	case COMP_DIR_XMIT:
  375: 	    Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
  376: 		stats.InOctets,
  377: 		stats.OutOctets,
  378: 		((stats.InOctets!=0)?
  379: 		    ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
  380: 		    0));
  381: 	    Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
  382: 		stats.FramesPlain,
  383: 		stats.FramesComp,
  384: 		stats.FramesUncomp);
  385: 	    Printf("\tErrors\t: %llu\r\n",
  386: 		stats.Errors);
  387: 	    break;
  388: 	case COMP_DIR_RECV:
  389: 	    Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
  390: 		stats.OutOctets,
  391: 		stats.InOctets,
  392: 		((stats.OutOctets!=0)?
  393: 		    ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
  394: 		    0));
  395: 	    Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
  396: 		stats.FramesPlain,
  397: 		stats.FramesComp,
  398: 		stats.FramesUncomp);
  399: 	    Printf("\tErrors\t: %llu\r\n",
  400: 		stats.Errors);
  401:     	    break;
  402: 	default:
  403:     	    assert(0);
  404:     }
  405:     return (0);
  406: }
  407: 
  408: #endif /* CCP_DEFLATE */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>