File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ccp_deflate.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (10 years, 11 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    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:     id = NgGetNodeID(-1, path);
  105:     if (dir == COMP_DIR_XMIT) {
  106: 	b->ccp.comp_node_id = id;
  107:     } else {
  108: 	b->ccp.decomp_node_id = id;
  109:     }
  110: 
  111:     /* Configure DEFLATE node */
  112:     snprintf(path, sizeof(path), "[%x]:", id);
  113:     if (NgSendMsg(gCcpCsock, path,
  114:     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_CONFIG, &conf, sizeof(conf)) < 0) {
  115: 	Perror("[%s] can't config %s node at %s",
  116:     	    b->name, NG_DEFLATE_NODE_TYPE, path);
  117: 	NgFuncShutdownNode(gCcpCsock, b->name, path);
  118: 	return(-1);
  119:     }
  120: 
  121:     return 0;
  122: }
  123: 
  124: /*
  125:  * DeflateConfigure()
  126:  */
  127: 
  128: static int
  129: DeflateConfigure(Bund b)
  130: {
  131:     CcpState	const ccp = &b->ccp;
  132:     DeflateInfo	const deflate = &ccp->deflate;
  133:   
  134:     deflate->xmit_windowBits=15;
  135:     deflate->recv_windowBits=0;
  136:   
  137:     return(0);
  138: }
  139: 
  140: /*
  141:  * DeflateCleanup()
  142:  */
  143: 
  144: static char *
  145: DeflateDescribe(Bund b, int dir, char *buf, size_t len)
  146: {
  147:     CcpState	const ccp = &b->ccp;
  148:     DeflateInfo	const deflate = &ccp->deflate;
  149: 
  150:     switch (dir) {
  151: 	case COMP_DIR_XMIT:
  152: 	    snprintf(buf, len, "win %d", deflate->xmit_windowBits);
  153: 	    break;
  154: 	case COMP_DIR_RECV:
  155: 	    snprintf(buf, len, "win %d", deflate->recv_windowBits);
  156: 	    break;
  157: 	default:
  158:     	    assert(0);
  159:     	    return(NULL);
  160:     }
  161:     return (buf);
  162: }
  163: 
  164: /*
  165:  * DeflateCleanup()
  166:  */
  167: 
  168: void
  169: DeflateCleanup(Bund b, int dir)
  170: {
  171:     char		path[NG_PATHSIZ];
  172: 
  173:     /* Remove node */
  174:     if (dir == COMP_DIR_XMIT) {
  175: 	snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
  176: 	b->ccp.comp_node_id = 0;
  177:     } else {
  178: 	snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
  179: 	b->ccp.decomp_node_id = 0;
  180:     }
  181:     NgFuncShutdownNode(gCcpCsock, b->name, path);
  182: }
  183: 
  184: /*
  185:  * DeflateRecvResetReq()
  186:  */
  187: 
  188: static Mbuf
  189: DeflateRecvResetReq(Bund b, int id, Mbuf bp, int *noAck)
  190: {
  191:     char		path[NG_PATHSIZ];
  192:     /* Forward ResetReq to the DEFLATE compression node */
  193:     snprintf(path, sizeof(path), "[%x]:", b->ccp.comp_node_id);
  194:     if (NgSendMsg(gCcpCsock, path,
  195:     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
  196: 	Perror("[%s] reset-req to %s node", b->name, NG_DEFLATE_NODE_TYPE);
  197:     }
  198:     return(NULL);
  199: }
  200: 
  201: /*
  202:  * DeflateSendResetReq()
  203:  */
  204: 
  205: static Mbuf
  206: DeflateSendResetReq(Bund b)
  207: {
  208:   return(NULL);
  209: }
  210: 
  211: /*
  212:  * DeflateRecvResetAck()
  213:  */
  214: 
  215: static void
  216: DeflateRecvResetAck(Bund b, int id, Mbuf bp)
  217: {
  218:     char		path[NG_PATHSIZ];
  219:     /* Forward ResetReq to the DEFLATE compression node */
  220:     snprintf(path, sizeof(path), "[%x]:", b->ccp.decomp_node_id);
  221:     if (NgSendMsg(gCcpCsock, path,
  222:     	    NGM_DEFLATE_COOKIE, NGM_DEFLATE_RESETREQ, NULL, 0) < 0) {
  223: 	Perror("[%s] reset-ack to %s node", b->name, NG_DEFLATE_NODE_TYPE);
  224:     }
  225: }
  226: 
  227: /*
  228:  * DeflateBuildConfigReq()
  229:  */
  230: 
  231: static u_char *
  232: DeflateBuildConfigReq(Bund b, u_char *cp, int *ok)
  233: {
  234:   CcpState	const ccp = &b->ccp;
  235:   DeflateInfo	const deflate = &ccp->deflate;
  236:   u_int16_t	opt;
  237:   
  238:   if (deflate->xmit_windowBits > 0) {
  239:     opt = ((deflate->xmit_windowBits-8)<<12) + (8<<8) + (0<<2) + 0;
  240:   
  241:     cp = FsmConfValue(cp, CCP_TY_DEFLATE, -2, &opt);
  242:     *ok = 1;
  243:   }
  244:   return (cp);
  245: }
  246: 
  247: /*
  248:  * DeflateDecodeConfigReq()
  249:  */
  250: 
  251: static void
  252: DeflateDecodeConfigReq(Fsm fp, FsmOption opt, int mode)
  253: {
  254:     Bund 	b = (Bund)fp->arg;
  255:   CcpState	const ccp = &b->ccp;
  256:   DeflateInfo	const deflate = &ccp->deflate;
  257:   u_int16_t     o;
  258:   u_char	window, method, chk;
  259: 
  260:   /* Sanity check */
  261:   if (opt->len != 4) {
  262:     Log(LG_CCP, ("[%s]     bogus length %d", b->name, opt->len));
  263:     if (mode == MODE_REQ)
  264:       FsmRej(fp, opt);
  265:     return;
  266:   }
  267: 
  268:   /* Get bits */
  269:   memcpy(&o, opt->data, 2);
  270:   o = ntohs(o);
  271:   window = (o>>12)&0x000F;
  272:   method = (o>>8)&0x000F;
  273:   chk = o&0x0003;
  274: 
  275:   /* Display it */
  276:   Log(LG_CCP, ("[%s]     0x%04x: w:%d, m:%d, c:%d", b->name, o, window, method, chk));
  277: 
  278:   /* Deal with it */
  279:   switch (mode) {
  280:     case MODE_REQ:
  281: 	if ((window > 0) && (window<=7) && (method == 8) && (chk == 0)) {
  282: 	    deflate->recv_windowBits = window + 8;
  283: 	    FsmAck(fp, opt);
  284: 	} else {
  285: 	    o = htons((7<<12) + (8<<8) + (0<<2) + 0);
  286: 	    memcpy(opt->data, &o, 2);
  287: 	    FsmNak(fp, opt);
  288: 	}
  289:       break;
  290: 
  291:     case MODE_NAK:
  292: 	if ((window > 0) && (window<=7) && (method == 8) && (chk == 0))
  293: 	    deflate->xmit_windowBits = window + 8;
  294: 	else {
  295: 	    deflate->xmit_windowBits = 0;
  296: 	}
  297:       break;
  298:   }
  299: }
  300: 
  301: /*
  302:  * DeflateNegotiated()
  303:  */
  304: 
  305: static int
  306: DeflateNegotiated(Bund b, int dir)
  307: {
  308:   return 1;
  309: }
  310: 
  311: /*
  312:  * DeflateSubtractBloat()
  313:  */
  314: 
  315: static int
  316: DeflateSubtractBloat(Bund b, int size)
  317: {
  318:   return(size + CCP_OVERHEAD);  /* Compression compensate header size */
  319: }
  320: 
  321: static int
  322: DeflateStat(Context ctx, int dir) 
  323: {
  324:     Bund			b = ctx->bund;
  325:     char			path[NG_PATHSIZ];
  326:     struct ng_deflate_stats	stats;
  327:     union {
  328: 	u_char			buf[sizeof(struct ng_mesg) + sizeof(stats)];
  329: 	struct ng_mesg		reply;
  330:     }				u;
  331: 
  332:     switch (dir) {
  333: 	case COMP_DIR_XMIT:
  334: 	    snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
  335: 		NG_PPP_HOOK_COMPRESS);
  336: 	    break;
  337: 	case COMP_DIR_RECV:
  338: 	    snprintf(path, sizeof(path), "mpd%d-%s:%s", gPid, b->name,
  339: 		NG_PPP_HOOK_DECOMPRESS);
  340: 	    break;
  341: 	default:
  342: 	    assert(0);
  343:     }
  344:     if (NgFuncSendQuery(path, NGM_DEFLATE_COOKIE, NGM_DEFLATE_GET_STATS, NULL, 0, 
  345: 	&u.reply, sizeof(u), NULL) < 0) {
  346: 	    Perror("[%s] can't get %s stats", b->name, NG_DEFLATE_NODE_TYPE);
  347: 	    return(0);
  348:     }
  349:     memcpy(&stats, u.reply.data, sizeof(stats));
  350:     switch (dir) {
  351: 	case COMP_DIR_XMIT:
  352: 	    Printf("\tBytes\t: %llu -> %llu (%+lld%%)\r\n",
  353: 		stats.InOctets,
  354: 		stats.OutOctets,
  355: 		((stats.InOctets!=0)?
  356: 		    ((int64_t)(stats.OutOctets - stats.InOctets)*100/(int64_t)stats.InOctets):
  357: 		    0));
  358: 	    Printf("\tFrames\t: %llu -> %lluc + %lluu\r\n",
  359: 		stats.FramesPlain,
  360: 		stats.FramesComp,
  361: 		stats.FramesUncomp);
  362: 	    Printf("\tErrors\t: %llu\r\n",
  363: 		stats.Errors);
  364: 	    break;
  365: 	case COMP_DIR_RECV:
  366: 	    Printf("\tBytes\t: %llu <- %llu (%+lld%%)\r\n",
  367: 		stats.OutOctets,
  368: 		stats.InOctets,
  369: 		((stats.OutOctets!=0)?
  370: 		    ((int64_t)(stats.InOctets - stats.OutOctets)*100/(int64_t)stats.OutOctets):
  371: 		    0));
  372: 	    Printf("\tFrames\t: %llu <- %lluc + %lluu\r\n",
  373: 		stats.FramesPlain,
  374: 		stats.FramesComp,
  375: 		stats.FramesUncomp);
  376: 	    Printf("\tErrors\t: %llu\r\n",
  377: 		stats.Errors);
  378:     	    break;
  379: 	default:
  380:     	    assert(0);
  381:     }
  382:     return (0);
  383: }
  384: 
  385: #endif /* CCP_DEFLATE */

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