]> git.ozlabs.org Git - ppp.git/blob - freebsd-2.2.8/patch.ppp_tty.c
Fix stack overflow. Bug report and fix from Alexandar Atanasov.
[ppp.git] / freebsd-2.2.8 / patch.ppp_tty.c
1 --- sys.stable/net/ppp_tty.c    Fri Apr 16 16:14:38 1999
2 +++ /usr/src/synclink/bsd2/ppp_tty.c    Thu Apr 15 14:40:51 1999
3 @@ -113,7 +113,10 @@
4  static int     pppinput __P((int c, struct tty *tp));
5  static int     pppstart __P((struct tty *tp));
6  
7 +static void    ppprcvframe __P((struct ppp_softc *sc, struct mbuf *m));
8 +
9  static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
10 +static void    pppsyncstart __P((register struct ppp_softc *sc));
11  static void    pppasyncstart __P((struct ppp_softc *));
12  static void    pppasyncctlp __P((struct ppp_softc *));
13  static void    pppasyncrelinq __P((struct ppp_softc *));
14 @@ -121,6 +124,7 @@
15  static void    ppp_timeout __P((void *));
16  static void    pppgetm __P((struct ppp_softc *sc));
17  static void    ppplogchar __P((struct ppp_softc *, int));
18 +static void    pppdumpframe __P((struct ppp_softc *sc,struct mbuf* m,int xmit));
19  
20  /* XXX called from if_ppp.c - layering violation */
21  void           pppasyncattach __P((void *));
22 @@ -473,6 +477,10 @@
23  
24      error = 0;
25      switch (cmd) {
26 +    case TIOCRCVFRAME:
27 +       ppprcvframe(sc,*((struct mbuf **)data));
28 +       break;
29 +       
30      case PPPIOCSASYNCMAP:
31         if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
32             break;
33 @@ -517,6 +525,111 @@
34      return error;
35  }
36  
37 +/* receive a complete ppp frame from device in synchronous
38 + * hdlc mode. caller gives up ownership of mbuf
39 + */
40 +static void ppprcvframe(struct ppp_softc *sc, struct mbuf *m)
41 +{
42 +       int len, s;
43 +       struct mbuf *n;
44 +       u_char hdr[4];
45 +       int hlen,count;
46 +               
47 +       for (n=m,len=0;n != NULL;n = n->m_next)
48 +               len += n->m_len;
49 +       if (len==0) {
50 +               m_freem(m);
51 +               return;
52 +       }
53 +       
54 +       /* extract PPP header from mbuf chain (1 to 4 bytes) */
55 +       for (n=m,hlen=0;n!=NULL && hlen<sizeof(hdr);n=n->m_next) {
56 +               count = (sizeof(hdr)-hlen) < n->m_len ?
57 +                               sizeof(hdr)-hlen : n->m_len;
58 +               bcopy(mtod(n,u_char*),&hdr[hlen],count);
59 +               hlen+=count;
60 +       }
61 +       
62 +       s = spltty();
63 +       
64 +       /* if AFCF compressed then prepend AFCF */
65 +       if (hdr[0] != PPP_ALLSTATIONS) {
66 +               if (sc->sc_flags & SC_REJ_COMP_AC) {
67 +                       if (sc->sc_flags & SC_DEBUG)
68 +                               printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
69 +                                       sc->sc_if.if_unit, hdr[0]);
70 +                               goto bail;
71 +                       }
72 +               M_PREPEND(m,2,M_DONTWAIT);              
73 +               if (m==NULL) {
74 +                       splx(s);
75 +                       return;
76 +               }
77 +               hdr[3] = hdr[1];
78 +               hdr[2] = hdr[0];
79 +               hdr[0] = PPP_ALLSTATIONS;
80 +               hdr[1] = PPP_UI;
81 +               len += 2;
82 +       }
83 +
84 +       /* if protocol field compressed, add MSB of protocol field = 0 */
85 +       if (hdr[2] & 1) {
86 +               /* a compressed protocol */
87 +               M_PREPEND(m,1,M_DONTWAIT);              
88 +               if (m==NULL) {
89 +                       splx(s);
90 +                       return;
91 +               }
92 +               hdr[3] = hdr[2];
93 +               hdr[2] = 0;
94 +               len++;
95 +       } 
96 +       
97 +       /* valid LSB of protocol field has bit0 set */
98 +       if (!(hdr[3] & 1)) {
99 +               if (sc->sc_flags & SC_DEBUG)
100 +                       printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
101 +                               (hdr[2] << 8) + hdr[3]);
102 +                       goto bail;
103 +       }
104 +       
105 +       /* packet beyond configured mru? */
106 +       if (len > sc->sc_mru + PPP_HDRLEN) {
107 +               if (sc->sc_flags & SC_DEBUG)
108 +                       printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
109 +               goto bail;
110 +       }
111 +       
112 +       /* add expanded 4 byte header to mbuf chain */
113 +       for (n=m,hlen=0;n!=NULL && hlen<sizeof(hdr);n=n->m_next) {
114 +               count = (sizeof(hdr)-hlen) < n->m_len ?
115 +                               sizeof(hdr)-hlen : n->m_len;
116 +               bcopy(&hdr[hlen],mtod(n,u_char*),count);
117 +               hlen+=count;
118 +       }
119 +       
120 +       /* if_ppp.c requires the PPP header and IP header */
121 +       /* to be contiguous */
122 +       count = len < MHLEN ? len : MHLEN;
123 +       if (m->m_len < count) {
124 +               m = m_pullup(m,count);
125 +               if (m==NULL)
126 +                       goto bail;
127 +       }
128 +       
129 +       sc->sc_stats.ppp_ibytes += len;
130 +       
131 +       if (sc->sc_flags & SC_LOG_RAWIN)
132 +               pppdumpframe(sc,m,0);
133 +    
134 +       ppppktin(sc, m, 0);
135 +       splx(s);
136 +       return;
137 +bail:  
138 +       m_freem(m);
139 +       splx(s);
140 +}
141 +
142  /*
143   * FCS lookup table as calculated by genfcstab.
144   */
145 @@ -566,6 +679,39 @@
146      return (fcs);
147  }
148  
149 +/* This gets called at splsoftnet from pppasyncstart at various times
150 + * when there is data ready to be sent.
151 + */
152 +static void pppsyncstart(register struct ppp_softc *sc)
153 +{
154 +       struct tty *tp = (struct tty *) sc->sc_devp;
155 +       struct mbuf *m, *n;
156 +       int len;
157 +    
158 +       for(m = sc->sc_outm;;) {
159 +               if (m == NULL) {
160 +                       m = ppp_dequeue(sc);    /* get new packet */
161 +                       if (m == NULL)
162 +                               break;          /* no more packets */
163 +                       if (sc->sc_flags & SC_DEBUG)
164 +                               pppdumpframe(sc,m,1);
165 +               }
166 +               microtime(&sc->sc_if.if_lastchange);
167 +               for(n=m,len=0;n!=NULL;n=n->m_next)
168 +                       len += n->m_len;
169 +                       
170 +               /* call device driver IOCTL to transmit a frame */
171 +               if ((*cdevsw[major(tp->t_dev)]->d_ioctl)
172 +                       (tp->t_dev,TIOCXMTFRAME,(caddr_t)&m,0,0)) {
173 +                       /* busy or error, set as current packet */
174 +                       sc->sc_outm = m;
175 +                       break;
176 +               }
177 +               sc->sc_outm = m = NULL;
178 +               sc->sc_stats.ppp_obytes += len;
179 +       }
180 +}
181 +
182  /*
183   * This gets called at splsoftnet from if_ppp.c at various times
184   * when there is data ready to be sent.
185 @@ -582,6 +728,11 @@
186      struct mbuf *m2;
187      int s;
188  
189 +    if (sc->sc_flags & SC_SYNC){
190 +       pppsyncstart(sc);
191 +       return;
192 +    }
193 +    
194      idle = 0;
195      /* XXX assumes atomic access to *tp although we're not at spltty(). */
196      while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
197 @@ -1125,6 +1276,44 @@
198                 sc->sc_rawin_count, sc->sc_rawin, " ");
199         sc->sc_rawin_count = 0;
200      }
201 +}
202 +
203 +static void pppdumpframe(struct ppp_softc *sc,struct mbuf* m,int xmit)
204 +{
205 +       int i,lcount,copycount,count;
206 +       char lbuf[16];
207 +       char *data;
208 +       
209 +       if (m == NULL)
210 +               return;
211 +               
212 +       for(count=m->m_len,data=mtod(m,char*);m != NULL;) {
213 +               /* build a line of output */
214 +               for(lcount=0;lcount < sizeof(lbuf);lcount += copycount) {
215 +                       if (!count) {
216 +                               m = m->m_next;
217 +                               if (m == NULL)
218 +                                       break;
219 +                               count = m->m_len;
220 +                               data  = mtod(m,char*);
221 +                       }
222 +                       copycount = (count > sizeof(lbuf)-lcount) ?
223 +                                       sizeof(lbuf)-lcount : count;
224 +                       bcopy(data,&lbuf[lcount],copycount);
225 +                       data  += copycount;
226 +                       count -= copycount;
227 +               }
228 +
229 +               /* output line (hex 1st, then ascii) */         
230 +               printf("ppp%d %s:",sc->sc_if.if_unit,xmit ? "output":"input ");
231 +               for(i=0;i<lcount;i++)
232 +                       printf("%02x ",(u_char)lbuf[i]);
233 +               for(;i<sizeof(lbuf);i++)
234 +                       printf("   ");
235 +               for(i=0;i<lcount;i++)
236 +                       printf("%c",(lbuf[i]>=040 && lbuf[i]<=0176)?lbuf[i]:'.');
237 +               printf("\n");
238 +       }
239  }
240  
241  #endif /* NPPP > 0 */