Nut/OS  4.10.3
API Reference
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$
00036  * Revision 1.7  2008/08/11 07:00:32  haraldkipp
00037  * BSD types replaced by stdint types (feature request #1282721).
00038  *
00039  * Revision 1.6  2006/10/05 17:25:41  haraldkipp
00040  * Avoid possible alignment errors. Fixes bug #1567748.
00041  *
00042  * Revision 1.5  2006/03/29 01:23:52  olereinhardt
00043  *  Signednes of strings
00044  *
00045  * Revision 1.4  2005/04/08 15:20:51  olereinhardt
00046  * added <sys/types.h> (__APPLE__) and <netinet/in.h> (__linux__)
00047  * for htons and simmilar.
00048  *
00049  * Revision 1.3  2004/03/08 11:27:24  haraldkipp
00050  * Accept incoming header compression.
00051  *
00052  * Revision 1.2  2003/08/14 15:16:22  haraldkipp
00053  * Echo, discard and protocol reject added
00054  *
00055  * Revision 1.1.1.1  2003/05/09 14:41:36  haraldkipp
00056  * Initial using 3.2.1
00057  *
00058  * Revision 1.1  2003/05/06 17:30:28  harald
00059  * Put in seperate module
00060  *
00061  */
00062 
00063 #include <net/netdebug.h>
00064 #include <sys/types.h>
00065 #include <dev/ahdlc.h>
00066 
00067 #include <arpa/inet.h>
00068 #include <netinet/ppp_fsm.h>
00069 #include <netinet/if_ppp.h>
00070 #include <netinet/in.h>
00071 FILE *__ppp_trs;                
00072 uint_fast8_t __ppp_trf;               
00074 static uint8_t ppp_header_sz;    /* Size of the PPP header. */
00075 
00076 static prog_char dbg_confreq[] = "[CONFREQ]";
00077 static prog_char dbg_confack[] = "[CONFACK]";
00078 static prog_char dbg_confnak[] = "[CONFNAK]";
00079 static prog_char dbg_confrej[] = "[CONFREJ]";
00080 static prog_char dbg_termreq[] = "[TERMREQ]";
00081 static prog_char dbg_termack[] = "[TERMACK]";
00082 static prog_char dbg_coderej[] = "[CODEREJ]";
00083 static prog_char dbg_protrej[] = "[PROTREJ]";
00084 static prog_char dbg_echoreq[] = "[ECHOREQ]";
00085 static prog_char dbg_echorsp[] = "[ECHORSP]";
00086 static prog_char dbg_discreq[] = "[DISCREQ]";
00087 
00088 
00089 void NutDumpLcpOption(FILE * stream, NETBUF * nb)
00090 {
00091     XCPOPT *xcpo;
00092     uint16_t len;
00093 
00094     if ((len = nb->nb_ap.sz) != 0)
00095         xcpo = nb->nb_ap.vp;
00096     else {
00097         len = nb->nb_dl.sz - ppp_header_sz - sizeof(XCPHDR);
00098         xcpo = (XCPOPT *) (((char *) nb->nb_dl.vp) + ppp_header_sz + sizeof(XCPHDR));
00099     }
00100     fprintf(stream, "[OPT(%u)]", len);
00101     while (len) {
00102         switch (xcpo->xcpo_type) {
00103         case LCP_MRU:
00104             fprintf(stream, "[MRU=%u]", ntohs(xcpo->xcpo_.us));
00105             break;
00106         case LCP_ASYNCMAP:
00107             fprintf(stream, "[ACCM=0x%08lX]", ntohl(xcpo->xcpo_.ul));
00108             break;
00109         case LCP_AUTHTYPE:
00110             fprintf(stream, "[AUTH=0x%04X]", ntohs(xcpo->xcpo_.us));
00111             break;
00112         case LCP_MAGICNUMBER:
00113             fprintf(stream, "[MAGIC=0x%08lX]", ntohl(xcpo->xcpo_.ul));
00114             break;
00115         case LCP_PCOMPRESSION:
00116             fputs("[PCOMP]", stream);
00117             break;
00118         case LCP_ACCOMPRESSION:
00119             fputs("[ACOMP]", stream);
00120             break;
00121         default:
00122             fprintf(stream, "[OPT%u?]", xcpo->xcpo_type);
00123             break;
00124         }
00125         if (len < xcpo->xcpo_len) {
00126             fputs("[LEN?]", stream);
00127             break;
00128         }
00129         len -= xcpo->xcpo_len;
00130         xcpo = (XCPOPT *) ((char *) xcpo + xcpo->xcpo_len);
00131     }
00132 }
00133 
00134 void NutDumpLcp(FILE * stream, NETBUF * nb)
00135 {
00136     XCPHDR *lcp;
00137     uint16_t len;
00138 
00139     if ((len = nb->nb_nw.sz) != 0) {
00140         len = nb->nb_nw.sz + nb->nb_ap.sz;
00141         lcp = nb->nb_nw.vp;
00142     } else {
00143         len = nb->nb_dl.sz - ppp_header_sz;
00144         lcp = (XCPHDR *) (((char *) nb->nb_dl.vp) + ppp_header_sz);
00145     }
00146     fprintf(stream, "[LCP-%03u(%u)]", lcp->xch_id, ntohs(lcp->xch_len));
00147     if (len < sizeof(XCPHDR)) {
00148         fputs("[LEN?]", stream);
00149         return;
00150     }
00151 
00152     switch (lcp->xch_code) {
00153     case XCP_CONFREQ:
00154         fputs_P(dbg_confreq, stream);
00155         NutDumpLcpOption(stream, nb);
00156         break;
00157 
00158     case XCP_CONFACK:
00159         fputs_P(dbg_confack, stream);
00160         NutDumpLcpOption(stream, nb);
00161         break;
00162 
00163     case XCP_CONFNAK:
00164         fputs_P(dbg_confnak, stream);
00165         NutDumpLcpOption(stream, nb);
00166         break;
00167 
00168     case XCP_CONFREJ:
00169         fputs_P(dbg_confrej, stream);
00170         NutDumpLcpOption(stream, nb);
00171         break;
00172 
00173     case XCP_TERMREQ:
00174         fputs_P(dbg_termreq, stream);
00175         break;
00176 
00177     case XCP_TERMACK:
00178         fputs_P(dbg_termack, stream);
00179         break;
00180 
00181     case XCP_CODEREJ:
00182         fputs_P(dbg_coderej, stream);
00183         break;
00184 
00185     case LCP_PROTREJ:
00186         fputs_P(dbg_protrej, stream);
00187         break;
00188     case LCP_ERQ:
00189         fputs_P(dbg_echoreq, stream);
00190         break;
00191     case LCP_ERP:
00192         fputs_P(dbg_echorsp, stream);
00193         break;
00194     case LCP_DRQ:
00195         fputs_P(dbg_discreq, stream);
00196         break;
00197 
00198     default:
00199         fprintf(stream, "[CODE%u?]", lcp->xch_code);
00200         break;
00201     }
00202 }
00203 
00204 void NutDumpPapOption(FILE * stream, NETBUF * nb)
00205 {
00206     char *xcpo;
00207     uint16_t len;
00208     uint8_t i;
00209 
00210     if ((len = nb->nb_ap.sz) != 0)
00211         xcpo = nb->nb_ap.vp;
00212     else {
00213         len = nb->nb_dl.sz - ppp_header_sz - sizeof(XCPHDR);
00214         xcpo = ((char *) nb->nb_dl.vp) + ppp_header_sz + sizeof(XCPHDR);
00215     }
00216     fprintf(stream, "[OPT(%u)]", len);
00217     while (len) {
00218         if (*xcpo) {
00219             fputc('[', stream);
00220             for (i = 1; i <= *xcpo; i++)
00221                 fputc(*(xcpo + i), stream);
00222             fputc(']', stream);
00223         }
00224         if (len < (uint16_t) (*xcpo + 1)) {
00225             fputs("[LEN?]", stream);
00226             break;
00227         }
00228         len -= *xcpo + 1;
00229         xcpo = xcpo + *xcpo + 1;
00230     }
00231 }
00232 
00233 void NutDumpPap(FILE * stream, NETBUF * nb)
00234 {
00235     XCPHDR *pap;
00236     uint16_t len;
00237 
00238     if ((len = nb->nb_nw.sz) != 0)
00239         pap = nb->nb_nw.vp;
00240     else {
00241         len = nb->nb_dl.sz - ppp_header_sz;
00242         pap = (XCPHDR *) (((char *) nb->nb_dl.vp) + ppp_header_sz);
00243     }
00244     fprintf(stream, "[PAP-%03u(%u)]", pap->xch_id, ntohs(pap->xch_len));
00245     if (len < sizeof(XCPHDR)) {
00246         fputs("[LEN?]", stream);
00247         return;
00248     }
00249 
00250     switch (pap->xch_code) {
00251     case XCP_CONFREQ:
00252         fputs_P(dbg_confreq, stream);
00253         NutDumpPapOption(stream, nb);
00254         break;
00255 
00256     case XCP_CONFACK:
00257         fputs_P(dbg_confack, stream);
00258         break;
00259 
00260     case XCP_CONFNAK:
00261         fputs_P(dbg_confnak, stream);
00262         break;
00263 
00264     default:
00265         fprintf(stream, "[CODE%u?]", pap->xch_code);
00266         break;
00267     }
00268 }
00269 
00270 void NutDumpIpcpOption(FILE * stream, NETBUF * nb)
00271 {
00272     XCPOPT *xcpo;
00273     uint16_t len;
00274 
00275     if ((len = nb->nb_ap.sz) != 0)
00276         xcpo = nb->nb_ap.vp;
00277     else {
00278         len = nb->nb_dl.sz - ppp_header_sz - sizeof(XCPHDR);
00279         xcpo = (XCPOPT *) (((char *) nb->nb_dl.vp) + ppp_header_sz + sizeof(XCPHDR));
00280     }
00281     fprintf(stream, "[OPT(%u)]", len);
00282     while (len) {
00283         switch (xcpo->xcpo_type) {
00284         case IPCP_ADDR:
00285             fprintf(stream, "[ADDR=%s]", inet_ntoa(xcpo->xcpo_.ul));
00286             break;
00287         case IPCP_COMPRESSTYPE:
00288             fputs("[COMP]", stream);
00289             break;
00290         case IPCP_MS_DNS1:
00291             fprintf(stream, "[DNS1=%s]", inet_ntoa(xcpo->xcpo_.ul));
00292             break;
00293         case IPCP_MS_DNS2:
00294             fprintf(stream, "[DNS2=%s]", inet_ntoa(xcpo->xcpo_.ul));
00295             break;
00296         default:
00297             fprintf(stream, "[OPT%u?]", xcpo->xcpo_type);
00298             break;
00299         }
00300         if (len < xcpo->xcpo_len) {
00301             fputs("[LEN?]", stream);
00302             break;
00303         }
00304         len -= xcpo->xcpo_len;
00305         xcpo = (XCPOPT *) ((char *) xcpo + xcpo->xcpo_len);
00306     }
00307 }
00308 
00309 void NutDumpIpcp(FILE * stream, NETBUF * nb)
00310 {
00311     XCPHDR *ipcp;
00312     uint16_t len;
00313 
00314     if ((len = nb->nb_nw.sz) != 0)
00315         ipcp = nb->nb_nw.vp;
00316     else {
00317         len = nb->nb_dl.sz - ppp_header_sz;
00318         ipcp = (XCPHDR *) (((char *) nb->nb_dl.vp) + ppp_header_sz);
00319     }
00320     fprintf(stream, "[IPCP-%03u(%u)]", ipcp->xch_id, ntohs(ipcp->xch_len));
00321     if (len < sizeof(XCPHDR)) {
00322         fputs("[LEN?]", stream);
00323         return;
00324     }
00325 
00326     switch (ipcp->xch_code) {
00327     case XCP_CONFREQ:
00328         fputs_P(dbg_confreq, stream);
00329         NutDumpIpcpOption(stream, nb);
00330         break;
00331 
00332     case XCP_CONFACK:
00333         fputs_P(dbg_confack, stream);
00334         NutDumpIpcpOption(stream, nb);
00335         break;
00336 
00337     case XCP_CONFNAK:
00338         fputs_P(dbg_confnak, stream);
00339         NutDumpIpcpOption(stream, nb);
00340         break;
00341 
00342     case XCP_CONFREJ:
00343         fputs_P(dbg_confrej, stream);
00344         NutDumpIpcpOption(stream, nb);
00345         break;
00346 
00347     case XCP_TERMREQ:
00348         fputs_P(dbg_termreq, stream);
00349         break;
00350 
00351     case XCP_TERMACK:
00352         fputs_P(dbg_termack, stream);
00353         break;
00354 
00355     case XCP_CODEREJ:
00356         fputs_P(dbg_coderej, stream);
00357         break;
00358 
00359     default:
00360         fprintf(stream, "[CODE%u?]", ipcp->xch_code);
00361         break;
00362     }
00363 }
00364 
00365 void NutDumpPpp(FILE * stream, NETBUF * nb)
00366 {
00367     PPPHDR *ph = (PPPHDR *) nb->nb_dl.vp;
00368     uint16_t protocol;
00369 
00370     fprintf(stream, "(%u)", nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz);
00371 
00372     /*
00373      * Check if the address and control field is compressed.
00374      * Thanks to Francois Rademeyer.
00375      */
00376     if (ph->address != AHDLC_ALLSTATIONS) {
00377 
00378         /*
00379          * Check for protocol compression.
00380          * LSB of 2nd octet for protocol is always 1.
00381          */
00382         if (((uint8_t *) nb->nb_dl.vp)[0] & 0x01) {
00383             ppp_header_sz = 1;
00384             protocol = *(uint8_t *) nb->nb_dl.vp;
00385         } else {
00386             char *cp = (char *)nb->nb_dl.vp;
00387             ppp_header_sz = 2;
00388             protocol = ntohs(((uint16_t)cp[0] << 8) | cp[1]);
00389         }
00390     } else {
00391         ppp_header_sz = sizeof(PPPHDR);
00392         protocol = ntohs(ph->prot_type);
00393     }
00394 
00395     if (nb->nb_dl.sz < ppp_header_sz) {
00396         fputs("[LEN?]", stream);
00397         return;
00398     }
00399 
00400     switch (protocol) {
00401     case PPP_IP:
00402         break;
00403 
00404     case PPP_LCP:
00405         NutDumpLcp(stream, nb);
00406         break;
00407 
00408     case PPP_IPCP:
00409         NutDumpIpcp(stream, nb);
00410         break;
00411 
00412     case PPP_PAP:
00413         NutDumpPap(stream, nb);
00414         break;
00415 
00416     default:
00417         fprintf(stream, "[TYPE 0x%04X?]", ntohs(ph->prot_type));
00418         break;
00419     }
00420 }
00421 
00429 void NutTracePPP(FILE * stream, uint8_t flags)
00430 {
00431     if (stream)
00432         __ppp_trs = stream;
00433     if (__ppp_trs)
00434         __ppp_trf = flags;
00435     else
00436         __ppp_trf = 0;
00437 }