📄 ipcp.c
字号:
/* ipcp.c - PPP IP Control Protocol *//* Copyright 1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1989 Carnegie Mellon University. * 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 Carnegie Mellon University. The name of the * University 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. *//*modification history--------------------01e,16jun95,dzb header file consolidation.01d,08jun95,dzb made LOG_NOTICE message printed even w/o debug option.01c,07feb95,dab die() if IP address reject (SPR #4038).01b,16jan95,dab removed ipcp_script call. removed pathname.h inclusion.01a,21dec94,dab VxWorks port - first WRS version. +dzb added: path for ppp header files, WRS copyright.*/#include <vxWorks.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include "pppLib.h"/* * Callbacks for fsm code. (CI = Configuration Information) */static void ipcp_resetci __ARGS((fsm *)); /* Reset our CI */static int ipcp_cilen __ARGS((fsm *)); /* Return length of our CI */static void ipcp_addci __ARGS((fsm *, u_char *, int *)); /* Add our CI */static int ipcp_ackci __ARGS((fsm *, u_char *, int)); /* Peer ack'd our CI */static int ipcp_nakci __ARGS((fsm *, u_char *, int)); /* Peer nak'd our CI */static int ipcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */static int ipcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv CI */static void ipcp_up __ARGS((fsm *)); /* We're UP */static void ipcp_down __ARGS((fsm *)); /* We're DOWN */static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ ipcp_resetci, /* Reset our Configuration Information */ ipcp_cilen, /* Length of our Configuration Information */ ipcp_addci, /* Add our Configuration Information */ ipcp_ackci, /* ACK our Configuration Information */ ipcp_nakci, /* NAK our Configuration Information */ ipcp_rejci, /* Reject our Configuration Information */ ipcp_reqci, /* Request peer's Configuration Information */ ipcp_up, /* Called when fsm reaches OPENED state */ ipcp_down, /* Called when fsm leaves OPENED state */ NULL, /* Called when we want the lower layer up */ NULL, /* Called when we want the lower layer down */ NULL, /* Called when Protocol-Reject received */ NULL, /* Retransmission is necessary */ NULL, /* Called to handle protocol-specific codes */ "IPCP" /* String name of protocol */};/* * Lengths of configuration options. */#define CILEN_VOID 2#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */#define CILEN_ADDR 6 /* new-style single address option */#define CILEN_ADDRS 10 /* old-style dual address option */#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ")/* * Make a string representation of a network IP address. */char *ip_ntoa(ipaddr) u_long ipaddr;{ static char b[64]; ipaddr = ntohl(ipaddr); sprintf(b, "%d.%d.%d.%d", (u_char)(ipaddr >> 24), (u_char)(ipaddr >> 16), (u_char)(ipaddr >> 8), (u_char)(ipaddr)); return b;}/* * ipcp_init - Initialize IPCP. */voidipcp_init(unit) int unit;{ fsm *f = &ppp_if[unit]->ipcp_fsm; ipcp_options *wo = &ppp_if[unit]->ipcp_wantoptions; ipcp_options *ao = &ppp_if[unit]->ipcp_allowoptions; f->unit = unit; f->protocol = IPCP; f->callbacks = &ipcp_callbacks; fsm_init(&ppp_if[unit]->ipcp_fsm); wo->neg_addr = 1; wo->old_addrs = 0; wo->ouraddr = 0; wo->hisaddr = 0; wo->neg_vj = 1; wo->old_vj = 0; wo->vj_protocol = IPCP_VJ_COMP; wo->maxslotindex = MAX_STATES - 1; /* really max index */ wo->cflag = 1; /* max slots and slot-id compression are currently hardwired in */ /* ppp_if.c to 16 and 1, this needs to be changed (among other */ /* things) gmc */ ao->neg_addr = 1; ao->neg_vj = 1; ao->maxslotindex = MAX_STATES - 1; ao->cflag = 1;}/* * ipcp_open - IPCP is allowed to come up. */voidipcp_open(unit) int unit;{ fsm_open(&ppp_if[unit]->ipcp_fsm);}/* * ipcp_close - Take IPCP down. */voidipcp_close(unit) int unit;{ fsm_close(&ppp_if[unit]->ipcp_fsm); /* * NB * Since the only NCP supported by VxWorks is IPCP, this routine should * also take down the entire link if IPCP is going down... Thus, * an LCP should occur so that an LCP terminate request is sent to the * peer. This is *not* usual behavior, especially in regard to the * RFC's protocol specification, but it makes sense for VxWorks. * Users should not mind, since the link is useless without IPCP. * -dzb */ die(unit, 1);}/* * ipcp_lowerup - The lower layer is up. */voidipcp_lowerup(unit) int unit;{ fsm_lowerup(&ppp_if[unit]->ipcp_fsm);}/* * ipcp_lowerdown - The lower layer is down. */voidipcp_lowerdown(unit) int unit;{ fsm_lowerdown(&ppp_if[unit]->ipcp_fsm);}/* * ipcp_input - Input IPCP packet. */voidipcp_input(unit, p, len) int unit; u_char *p; int len;{ fsm_input(&ppp_if[unit]->ipcp_fsm, p, len);}/* * ipcp_protrej - A Protocol-Reject was received for IPCP. * * Pretend the lower layer went down, so we shut up. */voidipcp_protrej(unit) int unit;{ fsm_lowerdown(&ppp_if[unit]->ipcp_fsm);}/* * ipcp_resetci - Reset our CI. */static voidipcp_resetci(f) fsm *f;{ ipcp_options *wo = &ppp_if[f->unit]->ipcp_wantoptions; wo->req_addr = wo->neg_addr && ppp_if[f->unit]->ipcp_allowoptions.neg_addr; if (wo->ouraddr == 0) wo->accept_local = 1; if (wo->hisaddr == 0) wo->accept_remote = 1; ppp_if[f->unit]->ipcp_gotoptions = *wo; ppp_if[f->unit]->cis_received = 0;}/* * ipcp_cilen - Return length of our CI. */static intipcp_cilen(f) fsm *f;{ ipcp_options *go = &ppp_if[f->unit]->ipcp_gotoptions;#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) return (LENCIADDR(go->neg_addr, go->old_addrs) + LENCIVJ(go->neg_vj, go->old_vj));}/* * ipcp_addci - Add our desired CIs to a packet. */static voidipcp_addci(f, ucp, lenp) fsm *f; u_char *ucp; int *lenp;{ ipcp_options *wo = &ppp_if[f->unit]->ipcp_wantoptions; ipcp_options *go = &ppp_if[f->unit]->ipcp_gotoptions; ipcp_options *ho = &ppp_if[f->unit]->ipcp_hisoptions; int len = *lenp;#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ if (neg) { \ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ if (len >= vjlen) { \ PUTCHAR(opt, ucp); \ PUTCHAR(vjlen, ucp); \ PUTSHORT(val, ucp); \ if (!old) { \ PUTCHAR(maxslotindex, ucp); \ PUTCHAR(cflag, ucp); \ } \ len -= vjlen; \ } else \ neg = 0; \ }#define ADDCIADDR(opt, neg, old, val1, val2) \ if (neg) { \ int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ if (len >= addrlen) { \ u_long l; \ PUTCHAR(opt, ucp); \ PUTCHAR(addrlen, ucp); \ l = ntohl(val1); \ PUTLONG(l, ucp); \ if (old) { \ l = ntohl(val2); \ PUTLONG(l, ucp); \ } \ len -= addrlen; \ } else \ neg = 0; \ } /* * First see if we want to change our options to the old * forms because we have received old forms from the peer. */ if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { /* use the old style of address negotiation */ go->neg_addr = 1; go->old_addrs = 1; } if (wo->neg_vj && !go->neg_vj && !go->old_vj) { /* try an older style of VJ negotiation */ if (ppp_if[f->unit]->cis_received == 0) { /* keep trying the new style until we see some CI from the peer */ go->neg_vj = 1; } else { /* use the old style only if the peer did */ if (ho->neg_vj && ho->old_vj) { go->neg_vj = 1; go->old_vj = 1; go->vj_protocol = ho->vj_protocol; } } } ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, go->old_addrs, go->ouraddr, go->hisaddr); ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, go->maxslotindex, go->cflag); *lenp -= len;}/* * ipcp_ackci - Ack our CIs. * * Returns: * 0 - Ack was bad. * 1 - Ack was good. */static intipcp_ackci(f, p, len) fsm *f; u_char *p; int len;{ ipcp_options *go = &ppp_if[f->unit]->ipcp_gotoptions; u_short cilen, citype, cishort; u_long cilong; u_char cimaxslotindex, cicflag; /* * CIs must be in exactly the same order that we sent... * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ if (neg) { \ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ if ((len -= vjlen) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != vjlen || \ citype != opt) \ goto bad; \ GETSHORT(cishort, p); \ if (cishort != val) \ goto bad; \ if (!old) { \ GETCHAR(cimaxslotindex, p); \ if (cimaxslotindex != maxslotindex) \ goto bad; \ GETCHAR(cicflag, p); \ if (cicflag != cflag) \ goto bad; \ } \ }#define ACKCIADDR(opt, neg, old, val1, val2) \ if (neg) { \ int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ u_long l; \ if ((len -= addrlen) < 0) \ goto bad; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -