Changeset ce2c216 in rtems


Ignore:
Timestamp:
Sep 14, 2002, 6:18:50 PM (19 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
144b94f
Parents:
c019ff07
Message:

2002-09-14 Vyacheslav V. Burdjanadze <wr@…>

  • kern/uipc_mbuf.c, sys/mbuf.h, netinet/udp_usrreq.c: Add optional UDP broadcast forwarding support.
  • netinet/Makefile.am: Defined FORWARD_PROTOCOL to enabled UDP broadcast forwarding.
Location:
cpukit/libnetworking
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libnetworking/ChangeLog

    rc019ff07 rce2c216  
     12002-09-14      Vyacheslav V. Burdjanadze <wr@zelax.ru>
     2
     3        * kern/uipc_mbuf.c, sys/mbuf.h, netinet/udp_usrreq.c: Add
     4        optional UDP broadcast forwarding support.
     5        * netinet/Makefile.am: Defined FORWARD_PROTOCOL to enabled UDP
     6        broadcast forwarding.
     7
    182002-09-02      Ralf Corsepius <corsepiu@faw.uni-ulm.de>
    29
  • cpukit/libnetworking/kern/uipc_mbuf.c

    rc019ff07 rce2c216  
    355355/*
    356356 * Copy data from an mbuf chain starting "off" bytes from the beginning,
    357  * continuing for "len" bytes, into the indicated buffer.
    358  */
    359 void
     357 * continuing for "len" bytes, into the indicated buffer. Return -1 if requested
     358 * size is bigger than available
     359 */
     360int
    360361m_copydata(m, off, len, cp)
    361362        register struct mbuf *m;
     
    365366{
    366367        register unsigned count;
     368        struct mbuf *m0 = m;
    367369
    368370        if (off < 0 || len < 0)
    369371                panic("m_copydata");
    370372        while (off > 0) {
    371                 if (m == 0)
    372                         panic("m_copydata");
     373                if (m == 0) {
     374                        /*printf("m_copydata: offset > mbuf length (");
     375                        while(m0) {
     376                            printf("[%d] ",m0->m_len);
     377                            m0 = m0->m_next;
     378                        }
     379                        printf(")\n");*/
     380                        return -1;
     381                }
    373382                if (off < m->m_len)
    374383                        break;
     
    377386        }
    378387        while (len > 0) {
    379                 if (m == 0)
    380                         panic("m_copydata");
     388                if (m == 0) {
     389                        /*printf("m_copydata: length > mbuf length (");
     390                        while(m0) {
     391                            printf("[%d] ",m0->m_len);
     392                            m0 = m0->m_next;
     393                        }
     394                        printf(")\n");*/
     395                       
     396                        return -1;
     397                    }
    381398                count = min(m->m_len - off, len);
    382399                bcopy(mtod(m, caddr_t) + off, cp, count);
     
    386403                m = m->m_next;
    387404        }
     405    return 0;
    388406}
    389407
     
    700718 * chain if necessary.
    701719 */
    702 void
     720int
    703721m_copyback(m0, off, len, cp)
    704722        struct  mbuf *m0;
     
    718736                if (m->m_next == 0) {
    719737                        n = m_getclr(M_DONTWAIT, m->m_type);
    720                         if (n == 0)
    721                                 goto out;
     738                        if (n == 0) {
     739                                /*panic("m_copyback() : malformed chain\n");*/
     740                                return -1;
     741                                }
    722742                        n->m_len = min(MLEN, len + off);
    723743                        m->m_next = n;
     
    733753                off = 0;
    734754                totlen += mlen;
    735                 if (len == 0)
     755                if (len == 0) {
     756                        m->m_len = mlen;
    736757                        break;
     758                }
    737759                if (m->m_next == 0) {
    738760                        n = m_get(M_DONTWAIT, m->m_type);
    739                         if (n == 0)
    740                                 break;
     761                        if (n == 0) {
     762                                /*panic("m_copyback() : malformed chain 2\n");*/
     763                                return -1;
     764                                };
    741765                        n->m_len = min(MLEN, len);
    742766                        m->m_next = n;
    743767                }
     768                m->m_len = mlen;
    744769                m = m->m_next;
    745770        }
    746771out:    if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
    747772                m->m_pkthdr.len = totlen;
    748 }
     773        return 0;
     774}
  • cpukit/libnetworking/netinet/Makefile.am

    rc019ff07 rce2c216  
    2424
    2525AM_CPPFLAGS += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS -DDIAGNOSTIC \
    26     -DBOOTP_COMPAT
     26    -DBOOTP_COMPAT -DFORWARD_PROTOCOL
    2727
    2828$(LIB): $(OBJS)
  • cpukit/libnetworking/netinet/udp_usrreq.c

    rc019ff07 rce2c216  
    3535 */
    3636
     37
    3738#include <sys/param.h>
    3839#include <sys/queue.h>
     
    5051
    5152#include <net/if.h>
     53#include <net/pf.h>
    5254#include <net/route.h>
    5355
     
    6163#include <netinet/udp.h>
    6264#include <netinet/udp_var.h>
     65#include <time.h>
     66
     67#undef malloc
     68#undef free
    6369
    6470/*
     
    7278#endif
    7379SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW,
    74                 &udpcksum, 0, "");
    75 
    76 static int log_in_vain = 0;
    77 SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW,
    78         &log_in_vain, 0, "");
     80                &udpcksum, 0, "Calculate UDP checksum");
     81               
     82
     83#ifdef FORWARD_PROTOCOL
     84
     85static int
     86udp_store(struct mbuf *m);
     87
     88static int
     89udp_doutput(struct in_addr dst);
     90
     91
     92/*
     93 * To implement udp broadcast forwarding we should check ``broadcast storm''
     94 * condition that can be caused if there is alternate ways between two subnets
     95 * and efficiently cut such loops. This can be done by caching sensetive packet
     96 * information and performing tests on it:
     97 * 1. If we got packet that is not in our cache we pass this packet and
     98 *    add it into cache. If there is no room in cache - LRU packet is discarded
     99 * 2. If we got packet that already in our cache we make it MRU and:         
     100 *    We check ttl of ip packet - if it same or greater as in cache we just
     101 *    pass it. If it less - just drop this packet.
     102 */
     103
     104#define MAXUDPCACHE  10  /* Seems to be reasonable size */
     105#define UDPMAXEXPIRE 30  /* 30 sec expire cache         */
     106
     107struct packet_cache {
     108    unsigned8      pc_ttl;   /* IP packet TTL */
     109    unsigned16     pc_sum;   /* UDP packet checksum */
     110    struct in_addr pc_src;   /* IP packet source address*/
     111    struct udphdr  pc_uh;    /* UDP packet header */
     112    time_t  pc_time;         /* Expiry value */
     113    struct packet_cache *next , *prev;
     114   
     115};
     116
     117static struct packet_cache *udp_cache = NULL;
     118
     119#endif
     120
     121       
     122static u_long   udp_sendspace = 9216;           /* really max datagram size */
     123                                        /* 40 1K datagrams */
     124SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW,
     125        &udp_sendspace, 0, "Maximum UDP datagram size");
     126
     127static u_long   udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
     128SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
     129        &udp_recvspace, 0, "Maximum UDP receive buffer size");
     130       
    79131
    80132static struct   inpcbhead udb;          /* from udp_var.h */
     
    85137#endif
    86138
    87        struct   udpstat udpstat;        /* from udp_var.h */
    88 SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RD,
    89         &udpstat, udpstat, "");
     139/*
     140 * UDP statistics
     141 */
     142struct udpstat udpstat;
     143
     144SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW,
     145        &udpstat, udpstat, "UDP statistic");
    90146
    91147static struct   sockaddr_in udp_in = { sizeof(udp_in), AF_INET };
     
    95151                            struct mbuf *));
    96152static  void udp_notify __P((struct inpcb *, int));
     153
     154
     155/* Added by Vasilkov. This system call is used by snmp agent code.
     156 *
     157 */
     158void udp_get_struct_udb (struct inpcbhead * strudb)
     159{
     160        memcpy ((char*)strudb, (char*)&udb, sizeof(struct inpcbhead));
     161}
     162
     163
     164/*
     165 * Register sysctl's
     166 */
     167void
     168sysctl_register_udp_usrreq() {
     169
     170        sysctl_register(_net_inet_udp,checksum);
     171        sysctl_register(_net_inet_udp,maxdgram);
     172        sysctl_register(_net_inet_udp,stats);
     173        sysctl_register(_net_inet_udp,recvspace);
     174}
    97175
    98176void
     
    102180        udbinfo.listhead = &udb;
    103181        udbinfo.hashbase = hashinit(UDBHASHSIZE, M_PCB, &udbinfo.hashmask);
    104 }
     182       
     183}
     184
     185#ifdef FORWARD_PROTOCOL
     186static unsigned char udp_ports[65536/8];
     187
     188/*
     189 * Enable/Disable udp port forwarding
     190 */
     191int udp_forward_port(int port,int forward) {
     192
     193    int byte = port/8;
     194    int offset = port%8;
     195   
     196    if (forward)
     197        udp_ports[byte] |= (0x80 >> offset);
     198    else
     199        udp_ports[byte] &= ~(0x80 >> offset);
     200       
     201    return 0;
     202}
     203
     204/*
     205 * Check if port should be forwarded
     206 */
     207static int udp_if_forward(int port) {
     208
     209    int byte = port/8;
     210    int offset = port%8;
     211   
     212    return (udp_ports[byte] & (0x80 >> offset));
     213
     214}
     215
     216/*
     217 * Get packet_cache from mbuf
     218 */
     219static int udp_pc_from_m(struct packet_cache *pc, struct mbuf *m) {
     220
     221    struct ip *iph = mtod(m,struct ip *);
     222    struct udphdr *uh = (struct udphdr *)((char *)iph + sizeof(struct ip));
     223   
     224    pc->pc_ttl  = iph->ip_ttl;
     225    pc->pc_sum  = uh->uh_sum;
     226    pc->pc_src  = iph->ip_src;
     227    pc->pc_uh   = *uh;
     228    pc->pc_time = time(NULL) + UDPMAXEXPIRE;
     229   
     230    return 0;
     231}
     232
     233/*
     234 * Make cache entry MRU
     235 */
     236static void udp_make_mru(struct packet_cache *pc) {
     237
     238    if (pc == udp_cache)
     239        return ;
     240   
     241    /* MRU it */
     242    if (pc->prev) pc->prev->next = pc->next;
     243    if (pc->next) pc->next->prev = pc->prev;
     244   
     245    pc->prev = NULL;
     246    pc->next = udp_cache;
     247    udp_cache->prev = pc;
     248    udp_cache = pc;
     249   
     250    pc->pc_time = time(NULL) + UDPMAXEXPIRE;
     251   
     252    /*
     253     * HUGE FIXME: pc_sum should be strong checksum of udp data. md5 seems
     254     * to be ok.
     255     */
     256   
     257}
     258
     259
     260/*
     261 *
     262 */
     263#define UDP_PASS 0
     264#define UDP_DROP 1
     265
     266static int udp_analyze(struct mbuf *m) {
     267
     268    time_t now;
     269    struct packet_cache *pc,my,*empty = NULL;
     270   
     271   
     272    /*
     273     * If still no cache allocated - allocate it
     274     */
     275    if (!udp_cache) {
     276        int i;
     277       
     278        for (i=0;i<MAXUDPCACHE;i++) {
     279            struct packet_cache *pc = malloc(sizeof(struct packet_cache));
     280            if (pc) {
     281                memset(pc,0,sizeof(struct packet_cache));
     282                pc->next = udp_cache;
     283                if (udp_cache) udp_cache->prev = pc;
     284                udp_cache = pc;
     285            }
     286        }
     287    }
     288   
     289    /*
     290     * If no memory - just drop packet
     291     */
     292    if (!udp_cache)
     293        return UDP_DROP;
     294   
     295    pc = udp_cache;
     296    now = time(NULL);
     297   
     298    udp_pc_from_m(&my,m);
     299   
     300    if (my.pc_ttl <= IPTTLDEC)
     301        return UDP_DROP;
     302   
     303    while( pc ) {
     304   
     305        if (pc->pc_ttl) { /*Non-empty entry*/
     306            if (pc->pc_time < now) {
     307                pc->pc_ttl = 0;
     308                empty = pc;
     309#ifdef FORWARD_DEBUG           
     310/*              printf("Entry expired :%s, sum %lu\n",inet_ntoa(pc->pc_src),pc->pc_sum);*/
     311#endif         
     312            }
     313            else {
     314                if ((pc->pc_sum == my.pc_sum) &&
     315                    (pc->pc_src.s_addr == my.pc_src.s_addr) &&
     316                    (pc->pc_uh.uh_dport == my.pc_uh.uh_dport) &&
     317                    (pc->pc_uh.uh_ulen == my.pc_uh.uh_ulen)) {
     318                   
     319#ifdef FORWARD_DEBUG               
     320/*                      printf("Cache HIT\n");*/
     321#endif                 
     322                   
     323                        udp_make_mru(pc);
     324                        if (pc->pc_ttl <= my.pc_ttl)
     325                            return UDP_PASS;
     326                       
     327#ifdef FORWARD_DEBUG                   
     328/*                      printf("Loop detected!\n");*/
     329#endif                 
     330                        return UDP_DROP;
     331                    }
     332                   
     333            }
     334        }
     335        else
     336            empty = pc;
     337   
     338        pc = pc->next;
     339    }
     340   
     341    /*
     342     * If no free entry in cache - remove LRU entry
     343     */
     344    if (!empty) {
     345   
     346#ifdef FORWARD_DEBUG   
     347/*      printf("Cache full, removing LRU\n");*/
     348#endif 
     349        empty = udp_cache;
     350        while(empty->next)
     351            empty = empty->next;
     352       
     353    }
     354   
     355    /* Cache it and make MRU */
     356#ifdef FORWARD_DEBUG   
     357/*    printf("Caching packet\n");*/
     358#endif   
     359    udp_make_mru(empty);
     360   
     361    empty->pc_ttl  = my.pc_ttl;
     362    empty->pc_sum  = my.pc_sum;
     363    empty->pc_src  = my.pc_src;
     364    empty->pc_uh   = my.pc_uh;
     365    empty->pc_time = my.pc_time;
     366
     367    return UDP_PASS;
     368}
     369
     370
     371
     372#endif /* FORWARD_PROTOCOL */
    105373
    106374void
     
    115383        int len;
    116384        struct ip save_ip;
     385        struct ifnet *ifp = m->m_pkthdr.rcvif;
     386        int log_in_vain = 0;
     387        int blackhole = 0;
     388
     389
     390        /*
     391         * Fetch logging flag from interface
     392         */     
     393        if (ifp->if_ip.ifi_udp & IFNET_UDP_LOG_IN_VAIN)
     394            log_in_vain = 1;
     395           
     396        /*
     397         * Check if we should silently discard refused connects
     398         */
     399        if (ifp->if_ip.ifi_udp & IFNET_UDP_BLACKHOLE)
     400            blackhole = 1;
    117401
    118402        udpstat.udps_ipackets++;
     
    140424                ip = mtod(m, struct ip *);
    141425        }
    142         uh = (struct udphdr *)((caddr_t)ip + iphlen);
     426        uh = (struct udphdr *)((caddr_t)ip + iphlen);
     427
     428#ifdef FORWARD_PROTOCOL   
     429        if (udp_if_forward(ntohs(uh->uh_dport))) {
     430            if (in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
     431                udp_store(m);
     432        }
     433#endif 
     434
    143435
    144436        /*
     
    164456         * Checksum extended UDP header and data.
    165457         */
     458
    166459        if (uh->uh_sum) {
     460               
    167461                ((struct ipovly *)ip)->ih_next = 0;
    168462                ((struct ipovly *)ip)->ih_prev = 0;
     
    180474            in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
    181475                struct inpcb *last;
     476               
     477#ifdef FORWARD_PROTOCOL         
     478                /*
     479                 * If our router configured to route broadcasts (this may
     480                 * be required to enable NetBIOS thru router)
     481                 */
     482
     483                if (udp_if_forward(ntohs(uh->uh_dport))) {
     484                    /*
     485                     * For each interface that allow directed broadcast
     486                     * we should reflect this packet with destanation address
     487                     * equal to interface subnet broadcast address
     488                     */
     489                    struct ifnet *ifp = ifnet;
     490                   
     491                    /*
     492                     * Checksum udp data + header without address information
     493                     */
     494                    m->m_len  -= sizeof(struct ip);
     495                    m->m_data += sizeof(struct ip);
     496                    uh->uh_sum = in_cksum(m, len/* + sizeof (struct ip)*/);
     497                    m->m_len  += sizeof(struct ip);
     498                    m->m_data -= sizeof(struct ip);
     499                   
     500                    *ip = save_ip;
     501                   
     502                    if (udp_analyze(m) == UDP_DROP) {
     503#ifdef FORWARD_DEBUG
     504                        printf("UDP DROP <%s:%d>, ttl=%d, sum=%lu\n",inet_ntoa(ip->ip_src),uh->uh_sport,ip->ip_ttl,uh->uh_sum);
     505#endif                                 
     506                        goto bad;
     507
     508                    }
     509                   
     510#ifdef FORWARD_DEBUG               
     511                    printf("UDP PASS <%s:%d>, ttl=%d, sum=%lu\n",inet_ntoa(ip->ip_src),uh->uh_sport,ip->ip_ttl,uh->uh_sum);
     512#endif             
     513
     514                   
     515                    while (ifp) {
     516                   
     517                        if ((ifp != m->m_pkthdr.rcvif) &&
     518                            !(ifp->if_flags & IFF_LOOPBACK) /*&&
     519                            (ifp->if_ip.ifi_udp & IFNET_UDP_FORWARD_PROTOCOL)*/) {
     520                           
     521                            struct ifaddr *ifa = ifp->if_addrlist;
     522                           
     523#ifdef FORWARD_DEBUG                       
     524                            /*printf("\tForwarding through %s%d\n",ifp->if_name,ifp->if_unit);*/
     525#endif                     
     526                           
     527                            while(ifa) {
     528
     529                               
     530                                if  (ifa->ifa_addr->sa_family == AF_INET) {
     531                   
     532
     533                               
     534                                    if (ifp->if_flags | IFF_BROADCAST) {
     535                                            if (ifa->ifa_dstaddr)
     536                                            ip->ip_dst.s_addr = ((struct sockaddr_in *)(ifa->ifa_dstaddr))->sin_addr.s_addr;
     537                                        else {
     538                                            ip->ip_dst.s_addr = ((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr;
     539                                            ip->ip_dst.s_addr &= ((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr;
     540                                            ip->ip_dst.s_addr |= ~(((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr);
     541                                        }
     542                                    }
     543                                    else
     544                                        goto bad;
     545                                       
     546                                    /*Calculate correct UDP checksum*/
     547                                   
     548                                   
     549#ifdef FORWARD_DEBUG
     550                                    printf("\t\tForwarding to %s\n",inet_ntoa(ip->ip_dst));
     551#endif
     552                                    udp_doutput(ip->ip_dst);
     553
     554                                }
     555
     556                                ifa = ifa->ifa_next;
     557                            }
     558                        }
     559                        ifp = ifp->if_next;
     560                    }
     561                   
     562                    if (opts)
     563                        m_freem(opts);
     564                    if (m)
     565                        m_freem(m);
     566                       
     567                    /*
     568                     * FIXME: should I also pass udp packet to socket?
     569                     */
     570
     571                    return ;
     572                }
     573#endif /* FORWARD_PROTOCOL */           
     574               
    182575                /*
    183576                 * Deliver a multicast or broadcast datagram to *all* sockets
     
    261654                         * for a broadcast or multicast datgram.)
    262655                         */
     656                        udpstat.udps_noport++;
    263657                        udpstat.udps_noportbcast++;
    264658                        goto bad;
     
    283677        if (inp == NULL) {
    284678                if (log_in_vain) {
    285                         char buf[4*sizeof "123"];
    286 
    287                         strcpy(buf, inet_ntoa(ip->ip_dst));
     679                        char bufdst[20];
     680                        char bufsrc[20];
     681                       
     682                        inet_ntop(AF_INET,&(ip->ip_dst),bufdst,sizeof(bufdst));
     683                        inet_ntop(AF_INET,&(ip->ip_src),bufdst,sizeof(bufsrc));
     684
    288685                        log(LOG_INFO, "Connection attempt to UDP %s:%d"
    289686                            " from %s:%d\n",
    290                                 buf, ntohs(uh->uh_dport),
    291                                 inet_ntoa(ip->ip_src), ntohs(uh->uh_sport));
     687                                bufdst, ntohs(uh->uh_dport),
     688                                bufsrc, ntohs(uh->uh_sport));
    292689                }
    293690                udpstat.udps_noport++;
     
    297694                }
    298695                *ip = save_ip;
     696               
     697                /*
     698                 * If we forced to be silent as much as possible..
     699                 */
     700                if (blackhole)
     701                    goto bad;
     702                   
    299703                icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
    300704                return;
     
    324728        m_freem(m);
    325729        if (opts)
    326                 m_freem(opts);
     730            m_freem(opts);
    327731}
    328732
     
    432836         */
    433837        ui->ui_sum = 0;
    434         if (udpcksum) {
     838        if (udpcksum) { /*FIXME: should be taken from ouput interface */
    435839            if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
    436840                ui->ui_sum = 0xffff;
     
    442846        error = ip_output(m, inp->inp_options, &inp->inp_route,
    443847            inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
    444             inp->inp_moptions);
     848            inp->inp_moptions,0);
    445849
    446850        if (addr) {
     
    456860}
    457861
    458 static u_long   udp_sendspace = 9216;           /* really max datagram size */
    459                                         /* 40 1K datagrams */
    460 SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW,
    461         &udp_sendspace, 0, "");
    462 
    463 static u_long   udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
    464 SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
    465         &udp_recvspace, 0, "");
    466862
    467863/*ARGSUSED*/
     
    502898                if (error)
    503899                        break;
    504                 ((struct inpcb *) so->so_pcb)->inp_ip_ttl = ip_defttl;
     900                ((struct inpcb *) so->so_pcb)->inp_ip_ttl = ip_defttl; /*FIXME: fetch ttl from interface first*/
    505901                break;
    506902
     
    6121008        splx(s);
    6131009}
     1010
     1011#ifdef FORWARD_PROTOCOL
     1012
     1013static int ttl;
     1014static struct in_addr src;
     1015static int sport,dport;
     1016static char buf[8096];
     1017static int len;
     1018
     1019/*
     1020 * Store packet
     1021 */
     1022static int
     1023udp_store(struct mbuf *m) {
     1024
     1025    struct ip *iph = mtod(m,struct ip *);
     1026    struct udphdr *uh = iph + 1;
     1027
     1028#ifdef FORWARD_DEBUG
     1029    printf("Storing %d bytes at offset %d of total packet len %d\n",uh->uh_ulen - sizeof(struct udphdr),sizeof(struct ip) + sizeof(struct udphdr),m->m_pkthdr.len);
     1030#endif   
     1031   
     1032    if (m_copydata(m,sizeof(struct ip) + sizeof(struct udphdr),
     1033                 uh->uh_ulen - sizeof(struct udphdr),
     1034                 buf)<0) {
     1035        ttl = 0;
     1036        return -1;
     1037    }
     1038                 
     1039
     1040    ttl = iph->ip_ttl;
     1041    src = iph->ip_src;
     1042    sport = uh->uh_sport;
     1043    dport = uh->uh_dport;
     1044    len = uh->uh_ulen - sizeof(struct udphdr);
     1045
     1046    return 0;
     1047}
     1048
     1049/*
     1050 * Pull packet to network
     1051 */
     1052static int
     1053udp_doutput(struct in_addr dst) {
     1054
     1055
     1056    struct udpiphdr *ui;
     1057    struct mbuf *m;
     1058    int error;
     1059    struct route ro;
     1060   
     1061    if (ttl <= 1)
     1062        return -1;
     1063   
     1064    m = m_gethdr(M_DONTWAIT,MT_DATA);
     1065       
     1066    if (!m) {
     1067#ifdef FORWARD_DEBUG   
     1068        printf("udp_doutput() : No buffers available\n");
     1069#endif 
     1070        return -1;
     1071    }
     1072
     1073    m->m_pkthdr.len = 0;
     1074    m->m_pkthdr.rcvif = NULL;   
     1075    m->m_len = MHLEN;
     1076   
     1077    if (m_copyback(m,0,len,buf)<0) {
     1078        m_freem(m);
     1079        return -1;
     1080    }
     1081   
     1082    M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
     1083   
     1084    if (!m) {
     1085#ifdef FORWARD_DEBUG   
     1086        printf("udp_douptut() : No buffers available\n");
     1087#endif 
     1088        return -1;
     1089    }
     1090
     1091    /*
     1092     * Fill in mbuf with extended UDP header
     1093     * and addresses and length put into network format.
     1094     */
     1095    ui = mtod(m, struct udpiphdr *);
     1096    ui->ui_next = ui->ui_prev = 0;
     1097    ui->ui_x1 = 0;
     1098    ui->ui_pr = IPPROTO_UDP;
     1099    ui->ui_len = htons((u_short)len + sizeof (struct udphdr));
     1100    ui->ui_src = src;
     1101    ui->ui_dst = dst;
     1102    ui->ui_sport = sport;
     1103    ui->ui_dport = dport;
     1104    ui->ui_ulen = ui->ui_len;
     1105
     1106    /*
     1107     * Stuff checksum and output datagram.
     1108     */
     1109    ui->ui_sum = 0;
     1110    if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
     1111        ui->ui_sum = 0xffff;
     1112       
     1113       
     1114    ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
     1115    ((struct ip *)ui)->ip_ttl = ttl - 1;
     1116    ((struct ip *)ui)->ip_tos = 0;
     1117   
     1118    bzero(&ro, sizeof ro);
     1119   
     1120    udpstat.udps_opackets++;
     1121
     1122#ifdef FORWARD_DEBUG   
     1123    {
     1124        struct mbuf *n = m;
     1125        printf("Sending buffer chain: ");
     1126        while (n) {
     1127            printf("[%d] ",n->m_len);
     1128            n = n->m_next;
     1129        }
     1130        printf("\n");
     1131       
     1132    }
     1133#endif   
     1134   
     1135    error = ip_output(m, NULL, &ro,IP_ALLOWBROADCAST,NULL,0);
     1136
     1137    if (ro.ro_rt)
     1138        RTFREE(ro.ro_rt);
     1139       
     1140    return error;
     1141}
     1142
     1143#endif /* FORWARD_PROTOCOL */
  • cpukit/libnetworking/sys/mbuf.h

    rc019ff07 rce2c216  
    408408int     m_mballoc __P((int, int));
    409409int     m_clalloc __P((int, int));
    410 void    m_copyback __P((struct mbuf *, int, int, caddr_t));
    411 void    m_copydata __P((struct mbuf *,int,int,caddr_t));
     410int     m_copyback __P((struct mbuf *, int, int, caddr_t));
     411int     m_copydata __P((struct mbuf *, int, int, caddr_t));
    412412void    m_freem __P((struct mbuf *));
    413413void    m_reclaim __P((void));
Note: See TracChangeset for help on using the changeset viewer.