pppdebug.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2004 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log: pppdebug.c,v $
00036  * Revision 1.6  2006/10/05 17:25:41  haraldkipp
00037  * Avoid possible alignment errors. Fixes bug #1567748.
00038  *
00039  * Revision 1.5  2006/03/29 01:23:52  olereinhardt
00040  *  Signednes of strings
00041  *
00042  * Revision 1.4  2005/04/08 15:20:51  olereinhardt
00043  * added <sys/types.h> (__APPLE__) and <netinet/in.h> (__linux__)
00044  * for htons and simmilar.
00045  *
00046  * Revision 1.3  2004/03/08 11:27:24  haraldkipp
00047  * Accept incoming header compression.
00048  *
00049  * Revision 1.2  2003/08/14 15:16:22  haraldkipp
00050  * Echo, discard and protocol reject added
00051  *
00052  * Revision 1.1.1.1  2003/05/09 14:41:36  haraldkipp
00053  * Initial using 3.2.1
00054  *
00055  * Revision 1.1  2003/05/06 17:30:28  harald
00056  * Put in seperate module
00057  *
00058  */
00059 
00060 #include <net/netdebug.h>
00061 #include <sys/types.h>
00062 #include <dev/ahdlc.h>
00063 
00064 #include <arpa/inet.h>
00065 #include <netinet/ppp_fsm.h>
00066 #include <netinet/if_ppp.h>
00067 #include <netinet/in.h>
00068 FILE *__ppp_trs;                
00069 u_char __ppp_trf;               
00071 static u_char ppp_header_sz;    /* Size of the PPP header. */
00072 
00073 static prog_char dbg_confreq[] = "[CONFREQ]";
00074 static prog_char dbg_confack[] = "[CONFACK]";
00075 static prog_char dbg_confnak[] = "[CONFNAK]";
00076 static prog_char dbg_confrej[] = "[CONFREJ]";
00077 static prog_char dbg_termreq[] = "[TERMREQ]";
00078 static prog_char dbg_termack[] = "[TERMACK]";
00079 static prog_char dbg_coderej[] = "[CODEREJ]";
00080 static prog_char dbg_protrej[] = "[PROTREJ]";
00081 static prog_char dbg_echoreq[] = "[ECHOREQ]";
00082 static prog_char dbg_echorsp[] = "[ECHORSP]";
00083 static prog_char dbg_discreq[] = "[DISCREQ]";
00084 
00085 
00086 void NutDumpLcpOption(FILE * stream, NETBUF * nb)
00087 {
00088     XCPOPT *xcpo;
00089     u_short len;
00090 
00091     if ((len = nb->nb_ap.sz) != 0)
00092         xcpo = nb->nb_ap.vp;
00093     else {
00094         len = nb->nb_dl.sz - ppp_header_sz - sizeof(XCPHDR);
00095         xcpo = (XCPOPT *) (((char *) nb->nb_dl.vp) + ppp_header_sz + sizeof(XCPHDR));
00096     }
00097     fprintf(stream, "[OPT(%u)]", len);
00098     while (len) {
00099         switch (xcpo->xcpo_type) {
00100         case LCP_MRU:
00101             fprintf(stream, "[MRU=%u]", ntohs(xcpo->xcpo_.us));
00102             break;
00103         case LCP_ASYNCMAP:
00104             fprintf(stream, "[ACCM=0x%08lX]", ntohl(xcpo->xcpo_.ul));
00105             break;
00106         case LCP_AUTHTYPE:
00107             fprintf(stream, "[AUTH=0x%04X]", ntohs(xcpo->xcpo_.us));
00108             break;
00109         case LCP_MAGICNUMBER:
00110             fprintf(stream, "[MAGIC=0x%08lX]", ntohl(xcpo->xcpo_.ul));
00111             break;
00112         case LCP_PCOMPRESSION:
00113             fputs("[PCOMP]", stream);
00114             break;
00115         case LCP_ACCOMPRESSION:
00116             fputs("[ACOMP]", stream);
00117             break;
00118         default:
00119             fprintf(stream, "[OPT%u?]", xcpo->xcpo_type);
00120             break;
00121         }
00122         if (len < xcpo->xcpo_len) {
00123             fputs("[LEN?]", stream);
00124             break;
00125         }
00126         len -= xcpo->xcpo_len;
00127         xcpo = (XCPOPT *) ((char *) xcpo + xcpo->xcpo_len);
00128     }
00129 }
00130 
00131 void NutDumpLcp(FILE * stream, NETBUF * nb)
00132 {
00133     XCPHDR *lcp;
00134     u_short len;
00135 
00136     if ((len = nb->nb_nw.sz) != 0) {
00137         len = nb->nb_nw.sz + nb->nb_ap.sz;
00138         lcp = nb->nb_nw.vp;
00139     } else {
00140         len = nb->nb_dl.sz - ppp_header_sz;
00141         lcp = (XCPHDR *) (((char *) nb->nb_dl.vp) + ppp_header_sz);
00142     }
00143     fprintf(stream, "[LCP-%03u(%u)]", lcp->xch_id, ntohs(lcp->xch_len));
00144     if (len < sizeof(XCPHDR)) {
00145         fputs("[LEN?]", stream);
00146         return;
00147     }
00148 
00149     switch (lcp->xch_code) {
00150     case XCP_CONFREQ:
00151         fputs_P(dbg_confreq, stream);
00152         NutDumpLcpOption(stream, nb);
00153         break;
00154 
00155     case XCP_CONFACK:
00156         fputs_P(dbg_confack, stream);
00157         NutDumpLcpOption(stream, nb);
00158         break;
00159 
00160     case XCP_CONFNAK:
00161         fputs_P(dbg_confnak, stream);
00162         NutDumpLcpOption(stream, nb);
00163         break;
00164 
00165     case XCP_CONFREJ:
00166         fputs_P(dbg_confrej, stream);
00167         NutDumpLcpOption(stream, nb);
00168         break;
00169 
00170     case XCP_TERMREQ:
00171         fputs_P(dbg_termreq, stream);
00172         break;
00173 
00174     case XCP_TERMACK:
00175         fputs_P(dbg_termack, stream);
00176         break;
00177 
00178     case XCP_CODEREJ:
00179         fputs_P(dbg_coderej, stream);
00180         break;
00181 
00182     case LCP_PROTREJ:
00183         fputs_P(dbg_protrej, stream);
00184         break;
00185     case LCP_ERQ:
00186         fputs_P(dbg_echoreq, stream);
00187         break;
00188     case LCP_ERP:
00189         fputs_P(dbg_echorsp, stream);
00190         break;
00191     case LCP_DRQ:
00192         fputs_P(dbg_discreq, stream);
00193         break;
00194 
00195     default:
00196         fprintf(stream, "[CODE%u?]", lcp->xch_code);
00197         break;
00198     }
00199 }
00200 
00201 void NutDumpPapOption(FILE * stream, NETBUF * nb)
00202 {
00203     char *xcpo;
00204     u_short len;
00205     u_char i;
00206 
00207     if ((len = nb->nb_ap.sz) != 0)
00208         xcpo = nb->nb_ap.vp;
00209     else {
00210         len = nb->nb_dl.sz - ppp_header_sz - sizeof(XCPHDR);
00211         xcpo = ((char *) nb->nb_dl.vp) + ppp_header_sz + sizeof(XCPHDR);
00212     }
00213     fprintf(stream, "[OPT(%u)]", len);
00214     while (len) {
00215         if (*xcpo) {
00216             fputc('[', stream);
00217             for (i = 1; i <= *xcpo; i++)
00218                 fputc(*(xcpo + i), stream);
00219             fputc(']', stream);
00220         }
00221         if (len < (u_short) (*xcpo + 1)) {
00222             fputs("[LEN?]", stream);
00223             break;
00224         }
00225         len -= *xcpo + 1;
00226         xcpo = xcpo + *xcpo + 1;
00227     }
00228 }
00229 
00230 void NutDumpPap(FILE * stream, NETBUF * nb)
00231 {
00232     XCPHDR *pap;
00233     u_short len;
00234 
00235     if ((len = nb->nb_nw.sz) != 0)
00236         pap = nb->nb_nw.vp;
00237     else {
00238         len = nb->nb_dl.sz - ppp_header_sz;
00239         pap = (XCPHDR *) (((char *) nb->nb_dl.vp) + ppp_header_sz);
00240     }
00241     fprintf(stream, "[PAP-%03u(%u)]", pap->xch_id, ntohs(pap->xch_len));
00242     if (len < sizeof(XCPHDR)) {
00243         fputs("[LEN?]", stream);
00244         return;
00245     }
00246 
00247     switch (pap->xch_code) {
00248     case XCP_CONFREQ:
00249         fputs_P(dbg_confreq, stream);
00250         NutDumpPapOption(stream, nb);
00251         break;
00252 
00253     case XCP_CONFACK:
00254         fputs_P(dbg_confack, stream);
00255         break;
00256 
00257     case XCP_CONFNAK:
00258         fputs_P(dbg_confnak, stream);
00259         break;
00260 
00261     default:
00262         fprintf(stream, "[CODE%u?]", pap->xch_code);
00263         break;
00264     }
00265 }
00266 
00267 void NutDumpIpcpOption(FILE * stream, NETBUF * nb)
00268 {
00269     XCPOPT *xcpo;
00270     u_short len;
00271 
00272     if ((len = nb->nb_ap.sz) != 0)
00273         xcpo = nb->nb_ap.vp;
00274     else {
00275         len = nb->nb_dl.sz - ppp_header_sz - sizeof(XCPHDR);
00276         xcpo = (XCPOPT *) (((char *) nb->nb_dl.vp) + ppp_header_sz + sizeof(XCPHDR));
00277     }
00278     fprintf(stream, "[OPT(%u)]", len);
00279     while (len) {
00280         switch (xcpo->xcpo_type) {
00281         case IPCP_ADDR:
00282             fprintf(stream, "[ADDR=%s]", inet_ntoa(xcpo->xcpo_.ul));
00283             break;
00284         case IPCP_COMPRESSTYPE:
00285             fputs("[COMP]", stream);
00286             break;
00287         case IPCP_MS_DNS1:
00288             fprintf(stream, "[DNS1=%s]", inet_ntoa(xcpo->xcpo_.ul));
00289             break;
00290         case IPCP_MS_DNS2:
00291             fprintf(stream, "[DNS2=%s]", inet_ntoa(xcpo->xcpo_.ul));
00292             break;
00293         default:
00294             fprintf(stream, "[OPT%u?]", xcpo->xcpo_type);
00295             break;
00296         }
00297         if (len < xcpo->xcpo_len) {
00298             fputs("[LEN?]", stream);
00299             break;
00300         }
00301         len -= xcpo->xcpo_len;
00302         xcpo = (XCPOPT *) ((char *) xcpo + xcpo->xcpo_len);
00303     }
00304 }
00305 
00306 void NutDumpIpcp(FILE * stream, NETBUF * nb)
00307 {
00308     XCPHDR *ipcp;
00309     u_short len;
00310 
00311     if ((len = nb->nb_nw.sz) != 0)
00312         ipcp = nb->nb_nw.vp;
00313     else {
00314         len = nb->nb_dl.sz - ppp_header_sz;
00315         ipcp = (XCPHDR *) (((char *) nb->nb_dl.vp) + ppp_header_sz);
00316     }
00317     fprintf(stream, "[IPCP-%03u(%u)]", ipcp->xch_id, ntohs(ipcp->xch_len));
00318     if (len < sizeof(XCPHDR)) {
00319         fputs("[LEN?]", stream);
00320         return;
00321     }
00322 
00323     switch (ipcp->xch_code) {
00324     case XCP_CONFREQ:
00325         fputs_P(dbg_confreq, stream);
00326         NutDumpIpcpOption(stream, nb);
00327         break;
00328 
00329     case XCP_CONFACK:
00330         fputs_P(dbg_confack, stream);
00331         NutDumpIpcpOption(stream, nb);
00332         break;
00333 
00334     case XCP_CONFNAK:
00335         fputs_P(dbg_confnak, stream);
00336         NutDumpIpcpOption(stream, nb);
00337         break;
00338 
00339     case XCP_CONFREJ:
00340         fputs_P(dbg_confrej, stream);
00341         NutDumpIpcpOption(stream, nb);
00342         break;
00343 
00344     case XCP_TERMREQ:
00345         fputs_P(dbg_termreq, stream);
00346         break;
00347 
00348     case XCP_TERMACK:
00349         fputs_P(dbg_termack, stream);
00350         break;
00351 
00352     case XCP_CODEREJ:
00353         fputs_P(dbg_coderej, stream);
00354         break;
00355 
00356     default:
00357         fprintf(stream, "[CODE%u?]", ipcp->xch_code);
00358         break;
00359     }
00360 }
00361 
00362 void NutDumpPpp(FILE * stream, NETBUF * nb)
00363 {
00364     PPPHDR *ph = (PPPHDR *) nb->nb_dl.vp;
00365     u_short protocol;
00366 
00367     fprintf(stream, "(%u)", nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz);
00368 
00369     /*
00370      * Check if the address and control field is compressed.
00371      * Thanks to Francois Rademeyer.
00372      */
00373     if (ph->address != AHDLC_ALLSTATIONS) {
00374 
00375         /*
00376          * Check for protocol compression.
00377          * LSB of 2nd octet for protocol is always 1.
00378          */
00379         if (((u_char *) nb->nb_dl.vp)[0] & 0x01) {
00380             ppp_header_sz = 1;
00381             protocol = *(u_char *) nb->nb_dl.vp;
00382         } else {
00383             char *cp = (char *)nb->nb_dl.vp;
00384             ppp_header_sz = 2;
00385             protocol = ntohs(((u_short)cp[0] << 8) | cp[1]);
00386         }
00387     } else {
00388         ppp_header_sz = sizeof(PPPHDR);
00389         protocol = ntohs(ph->prot_type);
00390     }
00391 
00392     if (nb->nb_dl.sz < ppp_header_sz) {
00393         fputs("[LEN?]", stream);
00394         return;
00395     }
00396 
00397     switch (protocol) {
00398     case PPP_IP:
00399         break;
00400 
00401     case PPP_LCP:
00402         NutDumpLcp(stream, nb);
00403         break;
00404 
00405     case PPP_IPCP:
00406         NutDumpIpcp(stream, nb);
00407         break;
00408 
00409     case PPP_PAP:
00410         NutDumpPap(stream, nb);
00411         break;
00412 
00413     default:
00414         fprintf(stream, "[TYPE 0x%04X?]", ntohs(ph->prot_type));
00415         break;
00416     }
00417 }
00418 
00426 void NutTracePPP(FILE * stream, u_char flags)
00427 {
00428     if (stream)
00429         __ppp_trs = stream;
00430     if (__ppp_trs)
00431         __ppp_trf = flags;
00432     else
00433         __ppp_trf = 0;
00434 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/