Annotation of ntddk/src/network/lance/packet.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1990  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     transfer.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module contains code to copy from ndis packets to ndis packets,
                     12:     and also to copy from ndis packets to a buffer.
                     13: 
                     14: Author:
                     15: 
                     16:     Anthony V. Ercolano (Tonye) 12-Sept-1990
                     17: 
                     18: Environment:
                     19: 
                     20:     Works in kernal mode, but is not important that it does.
                     21: 
                     22: Revision History:
                     23: 
                     24: 
                     25: --*/
                     26: 
                     27: #include <ndis.h>
                     28: #include <efilter.h>
                     29: #include <lancehrd.h>
                     30: #include <lancesft.h>
                     31: 
                     32: 
                     33: extern
                     34: VOID
                     35: LanceCopyFromPacketToBuffer(
                     36:     IN PNDIS_PACKET Packet,
                     37:     IN UINT Offset,
                     38:     IN UINT BytesToCopy,
                     39:     OUT PCHAR Buffer,
                     40:     OUT PUINT BytesCopied
                     41:     )
                     42: 
                     43: /*++
                     44: 
                     45: Routine Description:
                     46: 
                     47:     Copy from an ndis packet into a buffer.
                     48: 
                     49: Arguments:
                     50: 
                     51:     Packet - The packet to copy from.
                     52: 
                     53:     Offset - The offset from which to start the copy.
                     54: 
                     55:     BytesToCopy - The number of bytes to copy from the packet.
                     56: 
                     57:     Buffer - The destination of the copy.
                     58: 
                     59:     BytesCopied - The number of bytes actually copied.  Can be less then
                     60:     BytesToCopy if the packet is shorter than BytesToCopy.
                     61: 
                     62: Return Value:
                     63: 
                     64:     None
                     65: 
                     66: --*/
                     67: 
                     68: {
                     69: 
                     70:     //
                     71:     // Holds the number of ndis buffers comprising the packet.
                     72:     //
                     73:     UINT NdisBufferCount;
                     74: 
                     75:     //
                     76:     // Points to the buffer from which we are extracting data.
                     77:     //
                     78:     PNDIS_BUFFER CurrentBuffer;
                     79: 
                     80:     //
                     81:     // Holds the virtual address of the current buffer.
                     82:     //
                     83:     PVOID VirtualAddress;
                     84: 
                     85:     //
                     86:     // Holds the length of the current buffer of the packet.
                     87:     //
                     88:     UINT CurrentLength;
                     89: 
                     90:     //
                     91:     // Keep a local variable of BytesCopied so we aren't referencing
                     92:     // through a pointer.
                     93:     //
                     94:     UINT LocalBytesCopied = 0;
                     95: 
                     96:     //
                     97:     // Take care of boundary condition of zero length copy.
                     98:     //
                     99: 
                    100:     *BytesCopied = 0;
                    101:     if (!BytesToCopy) return;
                    102: 
                    103:     //
                    104:     // Get the first buffer.
                    105:     //
                    106: 
                    107:     NdisQueryPacket(
                    108:         Packet,
                    109:         NULL,
                    110:         &NdisBufferCount,
                    111:         &CurrentBuffer,
                    112:         NULL
                    113:         );
                    114: 
                    115:     //
                    116:     // Could have a null packet.
                    117:     //
                    118: 
                    119:     if (!NdisBufferCount) return;
                    120: 
                    121:     NdisQueryBuffer(
                    122:         CurrentBuffer,
                    123:         &VirtualAddress,
                    124:         &CurrentLength
                    125:         );
                    126: 
                    127:     while (LocalBytesCopied < BytesToCopy) {
                    128: 
                    129:         if (!CurrentLength) {
                    130: 
                    131:             NdisGetNextBuffer(
                    132:                 CurrentBuffer,
                    133:                 &CurrentBuffer
                    134:                 );
                    135: 
                    136:             //
                    137:             // We've reached the end of the packet.  We return
                    138:             // with what we've done so far. (Which must be shorter
                    139:             // than requested.
                    140:             //
                    141: 
                    142:             if (!CurrentBuffer) break;
                    143: 
                    144:             NdisQueryBuffer(
                    145:                 CurrentBuffer,
                    146:                 &VirtualAddress,
                    147:                 &CurrentLength
                    148:                 );
                    149:             continue;
                    150: 
                    151:         }
                    152: 
                    153:         //
                    154:         // Try to get us up to the point to start the copy.
                    155:         //
                    156: 
                    157:         if (Offset) {
                    158: 
                    159:             if (Offset > CurrentLength) {
                    160: 
                    161:                 //
                    162:                 // What we want isn't in this buffer.
                    163:                 //
                    164: 
                    165:                 Offset -= CurrentLength;
                    166:                 CurrentLength = 0;
                    167:                 continue;
                    168: 
                    169:             } else {
                    170: 
                    171:                 VirtualAddress = (PCHAR)VirtualAddress + Offset;
                    172:                 CurrentLength -= Offset;
                    173:                 Offset = 0;
                    174: 
                    175:             }
                    176: 
                    177:         }
                    178: 
                    179:         //
                    180:         // Copy the data.
                    181:         //
                    182: 
                    183: 
                    184:         {
                    185: 
                    186:             //
                    187:             // Holds the amount of data to move.
                    188:             //
                    189:             UINT AmountToMove;
                    190: 
                    191:             AmountToMove =
                    192:                        ((CurrentLength <= (BytesToCopy - LocalBytesCopied))?
                    193:                         (CurrentLength):(BytesToCopy - LocalBytesCopied));
                    194: 
                    195:             LANCE_MOVE_MEMORY(
                    196:                 Buffer,
                    197:                 VirtualAddress,
                    198:                 AmountToMove
                    199:                 );
                    200: 
                    201:             Buffer = (PCHAR)Buffer + AmountToMove;
                    202:             VirtualAddress = (PCHAR)VirtualAddress + AmountToMove;
                    203: 
                    204:             LocalBytesCopied += AmountToMove;
                    205:             CurrentLength -= AmountToMove;
                    206: 
                    207:         }
                    208: 
                    209:     }
                    210: 
                    211:     *BytesCopied = LocalBytesCopied;
                    212: 
                    213: }
                    214: 
                    215: extern
                    216: VOID
                    217: LanceCopyFromPacketToPacket(
                    218:     IN PNDIS_PACKET Destination,
                    219:     IN UINT DestinationOffset,
                    220:     IN UINT BytesToCopy,
                    221:     IN PNDIS_PACKET Source,
                    222:     IN UINT SourceOffset,
                    223:     OUT PUINT BytesCopied
                    224:     )
                    225: 
                    226: /*++
                    227: 
                    228: Routine Description:
                    229: 
                    230:     Copy from an ndis packet to an ndis packet.
                    231: 
                    232: Arguments:
                    233: 
                    234:     Destination - The packet should be copied in to.
                    235: 
                    236:     DestinationOffset - The offset from the beginning of the packet
                    237:     into which the data should start being placed.
                    238: 
                    239:     BytesToCopy - The number of bytes to copy from the source packet.
                    240: 
                    241:     Source - The ndis packet from which to copy data.
                    242: 
                    243:     SourceOffset - The offset from the start of the packet from which
                    244:     to start copying data.
                    245: 
                    246:     BytesCopied - The number of bytes actually copied from the source
                    247:     packet.  This can be less than BytesToCopy if the source or destination
                    248:     packet is too short.
                    249: 
                    250: Return Value:
                    251: 
                    252:     None
                    253: 
                    254: --*/
                    255: 
                    256: {
                    257: 
                    258:     //
                    259:     // Holds the count of the number of ndis buffers comprising the
                    260:     // destination packet.
                    261:     //
                    262:     UINT DestinationBufferCount;
                    263: 
                    264:     //
                    265:     // Holds the count of the number of ndis buffers comprising the
                    266:     // source packet.
                    267:     //
                    268:     UINT SourceBufferCount;
                    269: 
                    270:     //
                    271:     // Points to the buffer into which we are putting data.
                    272:     //
                    273:     PNDIS_BUFFER DestinationCurrentBuffer;
                    274: 
                    275:     //
                    276:     // Points to the buffer from which we are extracting data.
                    277:     //
                    278:     PNDIS_BUFFER SourceCurrentBuffer;
                    279: 
                    280:     //
                    281:     // Holds the virtual address of the current destination buffer.
                    282:     //
                    283:     PVOID DestinationVirtualAddress;
                    284: 
                    285:     //
                    286:     // Holds the virtual address of the current source buffer.
                    287:     //
                    288:     PVOID SourceVirtualAddress;
                    289: 
                    290:     //
                    291:     // Holds the length of the current destination buffer.
                    292:     //
                    293:     UINT DestinationCurrentLength;
                    294: 
                    295:     //
                    296:     // Holds the length of the current source buffer.
                    297:     //
                    298:     UINT SourceCurrentLength;
                    299: 
                    300:     //
                    301:     // Keep a local variable of BytesCopied so we aren't referencing
                    302:     // through a pointer.
                    303:     //
                    304:     UINT LocalBytesCopied = 0;
                    305: 
                    306:     //
                    307:     // Take care of boundary condition of zero length copy.
                    308:     //
                    309: 
                    310:     *BytesCopied = 0;
                    311:     if (!BytesToCopy) return;
                    312: 
                    313:     //
                    314:     // Get the first buffer of the destination.
                    315:     //
                    316: 
                    317:     NdisQueryPacket(
                    318:         Destination,
                    319:         NULL,
                    320:         &DestinationBufferCount,
                    321:         &DestinationCurrentBuffer,
                    322:         NULL
                    323:         );
                    324: 
                    325:     //
                    326:     // Could have a null packet.
                    327:     //
                    328: 
                    329:     if (!DestinationBufferCount) return;
                    330: 
                    331:     NdisQueryBuffer(
                    332:         DestinationCurrentBuffer,
                    333:         &DestinationVirtualAddress,
                    334:         &DestinationCurrentLength
                    335:         );
                    336: 
                    337:     //
                    338:     // Get the first buffer of the source.
                    339:     //
                    340: 
                    341:     NdisQueryPacket(
                    342:         Source,
                    343:         NULL,
                    344:         &SourceBufferCount,
                    345:         &SourceCurrentBuffer,
                    346:         NULL
                    347:         );
                    348: 
                    349:     //
                    350:     // Could have a null packet.
                    351:     //
                    352: 
                    353:     if (!SourceBufferCount) return;
                    354: 
                    355:     NdisQueryBuffer(
                    356:         SourceCurrentBuffer,
                    357:         &SourceVirtualAddress,
                    358:         &SourceCurrentLength
                    359:         );
                    360: 
                    361:     while (LocalBytesCopied < BytesToCopy) {
                    362: 
                    363:         //
                    364:         // Check to see whether we've exhausted the current destination
                    365:         // buffer.  If so, move onto the next one.
                    366:         //
                    367: 
                    368:         if (!DestinationCurrentLength) {
                    369: 
                    370:             NdisGetNextBuffer(
                    371:                 DestinationCurrentBuffer,
                    372:                 &DestinationCurrentBuffer
                    373:                 );
                    374: 
                    375:             if (!DestinationCurrentBuffer) {
                    376: 
                    377:                 //
                    378:                 // We've reached the end of the packet.  We return
                    379:                 // with what we've done so far. (Which must be shorter
                    380:                 // than requested.)
                    381:                 //
                    382: 
                    383:                 break;
                    384: 
                    385:             }
                    386: 
                    387:             NdisQueryBuffer(
                    388:                 DestinationCurrentBuffer,
                    389:                 &DestinationVirtualAddress,
                    390:                 &DestinationCurrentLength
                    391:                 );
                    392:             continue;
                    393: 
                    394:         }
                    395: 
                    396: 
                    397:         //
                    398:         // Check to see whether we've exhausted the current source
                    399:         // buffer.  If so, move onto the next one.
                    400:         //
                    401: 
                    402:         if (!SourceCurrentLength) {
                    403: 
                    404:             NdisGetNextBuffer(
                    405:                 SourceCurrentBuffer,
                    406:                 &SourceCurrentBuffer
                    407:                 );
                    408: 
                    409:             if (!SourceCurrentBuffer) {
                    410: 
                    411:                 //
                    412:                 // We've reached the end of the packet.  We return
                    413:                 // with what we've done so far. (Which must be shorter
                    414:                 // than requested.)
                    415:                 //
                    416: 
                    417:                 break;
                    418: 
                    419:             }
                    420: 
                    421:             NdisQueryBuffer(
                    422:                 SourceCurrentBuffer,
                    423:                 &SourceVirtualAddress,
                    424:                 &SourceCurrentLength
                    425:                 );
                    426:             continue;
                    427: 
                    428:         }
                    429: 
                    430:         //
                    431:         // Try to get us up to the point to start the copy.
                    432:         //
                    433: 
                    434:         if (DestinationOffset) {
                    435: 
                    436:             if (DestinationOffset > DestinationCurrentLength) {
                    437: 
                    438:                 //
                    439:                 // What we want isn't in this buffer.
                    440:                 //
                    441: 
                    442:                 DestinationOffset -= DestinationCurrentLength;
                    443:                 DestinationCurrentLength = 0;
                    444:                 continue;
                    445: 
                    446:             } else {
                    447: 
                    448:                 DestinationVirtualAddress = (PCHAR)DestinationVirtualAddress
                    449:                                             + DestinationOffset;
                    450:                 DestinationCurrentLength -= DestinationOffset;
                    451:                 DestinationOffset = 0;
                    452: 
                    453:             }
                    454: 
                    455:         }
                    456: 
                    457:         //
                    458:         // Try to get us up to the point to start the copy.
                    459:         //
                    460: 
                    461:         if (SourceOffset) {
                    462: 
                    463:             if (SourceOffset > SourceCurrentLength) {
                    464: 
                    465:                 //
                    466:                 // What we want isn't in this buffer.
                    467:                 //
                    468: 
                    469:                 SourceOffset -= SourceCurrentLength;
                    470:                 SourceCurrentLength = 0;
                    471:                 continue;
                    472: 
                    473:             } else {
                    474: 
                    475:                 SourceVirtualAddress = (PCHAR)SourceVirtualAddress
                    476:                                             + SourceOffset;
                    477:                 SourceCurrentLength -= SourceOffset;
                    478:                 SourceOffset = 0;
                    479: 
                    480:             }
                    481: 
                    482:         }
                    483: 
                    484:         //
                    485:         // Copy the data.
                    486:         //
                    487: 
                    488:         {
                    489: 
                    490:             //
                    491:             // Holds the amount of data to move.
                    492:             //
                    493:             UINT AmountToMove;
                    494: 
                    495:             //
                    496:             // Holds the amount desired remaining.
                    497:             //
                    498:             UINT Remaining = BytesToCopy - LocalBytesCopied;
                    499: 
                    500:             AmountToMove =
                    501:                        ((SourceCurrentLength <= DestinationCurrentLength)?
                    502:                         (SourceCurrentLength):(DestinationCurrentLength));
                    503: 
                    504:             AmountToMove = ((Remaining < AmountToMove)?
                    505:                             (Remaining):(AmountToMove));
                    506: 
                    507:             LANCE_MOVE_MEMORY(
                    508:                 DestinationVirtualAddress,
                    509:                 SourceVirtualAddress,
                    510:                 AmountToMove
                    511:                 );
                    512: 
                    513:             DestinationVirtualAddress =
                    514:                 (PCHAR)DestinationVirtualAddress + AmountToMove;
                    515:             SourceVirtualAddress =
                    516:                 (PCHAR)SourceVirtualAddress + AmountToMove;
                    517: 
                    518:             LocalBytesCopied += AmountToMove;
                    519:             SourceCurrentLength -= AmountToMove;
                    520:             DestinationCurrentLength -= AmountToMove;
                    521: 
                    522:         }
                    523: 
                    524:     }
                    525: 
                    526:     *BytesCopied = LocalBytesCopied;
                    527: 
                    528: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.